Help with 3 compiler warnings from g++

L

Louise Hoffman

Dear developers,

I have written this program which can be downloaded from
http://www.sendspace.com/file/3uqpq1

as a 8Kb zip file, but I get these 3 warnings

main.cpp:101: warning: comparison between signed and unsigned integer
expressions

Expr.cpp: In member function 'virtual std::string Expr::toString()':
Expr.cpp:14: warning: control reaches end of non-void function
Expr.cpp: In member function 'virtual double Expr::eval()':
Expr.cpp:12: warning: control reaches end of non-void function


I have no idea why I get the first one. The code in question is

for( int i = 0; i < expressions.size(); i++ ) {
cout said:
() << endl;
}


and for the other two warnings it is
double Expr::eval() {}
string Expr::toString() {}

If I make them void, then the program breaks, and I don't know how to
make it work then.

Can someone help me out here? =)

Hugs,
Louise
 
A

Alf P. Steinbach

* Louise Hoffman:
Dear developers,

I have written this program which can be downloaded from
http://www.sendspace.com/file/3uqpq1

as a 8Kb zip file, but I get these 3 warnings

main.cpp:101: warning: comparison between signed and unsigned integer
expressions

Expr.cpp: In member function 'virtual std::string Expr::toString()':
Expr.cpp:14: warning: control reaches end of non-void function
Expr.cpp: In member function 'virtual double Expr::eval()':
Expr.cpp:12: warning: control reaches end of non-void function


I have no idea why I get the first one. The code in question is

for( int i = 0; i < expressions.size(); i++ ) {

() << endl;
}

Presumably expressions.size() has unsigned result type such as size_t.

Comparing a value of signed type to a value of unsigned type is generally
unsafe, e.g. -1 > 0u will yield true due to the -1 being promoted to unsigned type.

One solution is to define e.g.

#include <standard_header_that_defines_ptrdiff_t>

typedef std::ptrdiff_t Size;
typedef Size Index;

template< typename T >
Size nElements( T const& collection ) { return Size( collection.size() ); }

and then write

for( Index i = 0; i < nElements( expressions ); ++i )
{
// ...
}

and for the other two warnings it is
double Expr::eval() {}
string Expr::toString() {}

Missing return.

Cheers & hth.,

- Alf
 
J

Juha Nieminen

Louise said:
double Expr::eval() {}
string Expr::toString() {}

If I make them void, then the program breaks, and I don't know how to
make it work then.

If you are telling that the functions return values, shouldn't you,
like, return some values from them?
 
V

Victor Bazarov

Pete said:
* Louise Hoffman:
Dear developers,

I have written this program which can be downloaded from
http://www.sendspace.com/file/3uqpq1

as a 8Kb zip file, but I get these 3 warnings

main.cpp:101: warning: comparison between signed and unsigned integer
expressions

Expr.cpp: In member function 'virtual std::string Expr::toString()':
Expr.cpp:14: warning: control reaches end of non-void function
Expr.cpp: In member function 'virtual double Expr::eval()':
Expr.cpp:12: warning: control reaches end of non-void function


I have no idea why I get the first one. The code in question is

for( int i = 0; i < expressions.size(); i++ ) {
cout << expressions->toString() << " = " << expressions-
eval
() << endl;
}


Presumably expressions.size() has unsigned result type such as size_t.

Comparing a value of signed type to a value of unsigned type is
generally unsafe, e.g. -1 > 0u will yield true due to the -1 being
promoted to unsigned type.


Since the value of i in the loop above is never negative, none of this
matters. The comparison works just fine.


What would happen if 'expressions.size()' yields 'INT_MAX + 2'? Since
it's unsigned, it can, right? So, when 'i' reaches 'INT_MAX', and has
to go on, the next is i++, which has undefined behavior, or does it?

V
 
A

Alf P. Steinbach

* Pete Becker:
* Louise Hoffman:
Dear developers,

I have written this program which can be downloaded from
http://www.sendspace.com/file/3uqpq1

as a 8Kb zip file, but I get these 3 warnings

main.cpp:101: warning: comparison between signed and unsigned integer
expressions

Expr.cpp: In member function 'virtual std::string Expr::toString()':
Expr.cpp:14: warning: control reaches end of non-void function
Expr.cpp: In member function 'virtual double Expr::eval()':
Expr.cpp:12: warning: control reaches end of non-void function


I have no idea why I get the first one. The code in question is

for( int i = 0; i < expressions.size(); i++ ) {
cout << expressions->toString() << " = " << expressions-
eval
() << endl;
}


Presumably expressions.size() has unsigned result type such as size_t.

Comparing a value of signed type to a value of unsigned type is
generally unsafe, e.g. -1 > 0u will yield true due to the -1 being
promoted to unsigned type.


Since the value of i in the loop above is never negative, none of this
matters. The comparison works just fine.


Yes, that's right.

In other cases, such as the one I gave as example, it doesn't work fine.

Which explains why the compiler warns, which the OP asked about.

Avoiding using unsigned types for ordinary numerical values is a simple way to
avoid the pitfall.

It also avoids the warnings :) (although I know that at least at some earlier
time in your opinion one should simply ignore them, I prefer clean compile, so
as not to miss some possibly important warning -- it's not that much work).


Cheers,

- Alf
 
J

James Kanze

* Louise Hoffman:
I have written this program which can be downloaded from
http://www.sendspace.com/file/3uqpq1
as a 8Kb zip file, but I get these 3 warnings
main.cpp:101: warning: comparison between signed and unsigned integer
expressions
Expr.cpp: In member function 'virtual std::string Expr::toString()':
Expr.cpp:14: warning: control reaches end of non-void function
Expr.cpp: In member function 'virtual double Expr::eval()':
Expr.cpp:12: warning: control reaches end of non-void function
I have no idea why I get the first one. The code in question is
for( int i = 0; i < expressions.size(); i++ ) {
cout << expressions->toString() << " = " << expressions-
eval
() << endl;
}

Presumably expressions.size() has unsigned result type such
as size_t.
Comparing a value of signed type to a value of unsigned type
is generally unsafe, e.g. -1 > 0u will yield true due to the
-1 being promoted to unsigned type.

Since the value of i in the loop above is never negative, none
of this matters. The comparison works just fine.

Unless the container has more than INT_MAX elements. (In which
case, Alf's solution fails too.) Int is the default integral
type in C++, but in this case, the standard library uses
std::size_t, so I use std::size_t, rather than mixing types
(with or without a cast):

for ( std::size_t i = 0 ; i < expressions.size() ; ++ i ) {
// ...
}

More often, of course, I'll use an iterator. (I am assuming
here that "expressions" has a standard container type.)
 
J

James Kanze

On 2009-04-13 16:39:38 -0400, Victor Bazarov <[email protected]> said:

[...]
That will never happen.

I've had it happen. On the machines I usually work on, size_t
is a 64 bit type (and int is only 32 bits), and once or twice,
I've had arrays (generally byte arrays resulting from a
mmap---but not always) with more than 2^32 elements.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,147
Latest member
CarenSchni
Top