Comparing signed and unsigned values

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

int main()
{
bool foo=false;
for( unsigned int bar=0; bar < (foo?1:2); bar++ ) {
bar=42;
}
return 0;
}

A certain C++ compiler I am using claims that there exists in the
above code (on the line with the for loop) a comparison between a
signed and unsigned value. g++ invoked with strict options remains
silent. Is there any merit to the certain compiler's claim that
signed and unsigned values are being compared?

My guess is no, given that on

int main( void )
{
for( unsigned int bar=0; bar < (false?1:2); bar++ ) {
bar=42;
}
return 0;
}

the same compiler is silent.
 
R

REH

Christopher said:
int main()
{
bool foo=false;
for( unsigned int bar=0; bar < (foo?1:2); bar++ ) {
bar=42;
}
return 0;
}

A certain C++ compiler I am using claims that there exists in the
above code (on the line with the for loop) a comparison between a
signed and unsigned value. g++ invoked with strict options remains
silent. Is there any merit to the certain compiler's claim that
signed and unsigned values are being compared?

My guess is no, given that on

int main( void )
{
for( unsigned int bar=0; bar < (false?1:2); bar++ ) {
bar=42;
}
return 0;
}

the same compiler is silent.

1 and 2 are signed constants. Try 1u and 2u.

REH
 
C

Christopher Benson-Manica

REH said:
1 and 2 are signed constants. Try 1u and 2u.

That did silence the warning, although I find it strange that it would
warn on the code I posted and never on, say,

for( unsigned int foo=0; foo < 5; foo++ );

since foo < 5 should be the same signed/unsigned comparison that it
complains about on the code I posted.
 
A

Andrey Tarasevich

Christopher said:
int main()
{
bool foo=false;
for( unsigned int bar=0; bar < (foo?1:2); bar++ ) {
bar=42;
}
return 0;
}

A certain C++ compiler I am using claims that there exists in the
above code (on the line with the for loop) a comparison between a
signed and unsigned value.

That's true. The result of the 'foo?1:2' expression is signed, while 'bar' is
unsigned.
g++ invoked with strict options remains
silent.

Language specification does not define situations when warnings should (or
should not) be issued. Warnings are implementation-dependent. And they are
largely a QoI issue.
Is there any merit to the certain compiler's claim that
signed and unsigned values are being compared?

Yes. See above.
My guess is no, given that on

int main( void )
{
for( unsigned int bar=0; bar < (false?1:2); bar++ ) {
bar=42;
}
return 0;
}

the same compiler is silent.

In this case the compiler decided not to issue a waring (although technically it
could), while in the previous case it decided to issue one. It might also depend
on the compiler settings.
 
A

Andrey Tarasevich

Christopher said:
That did silence the warning, although I find it strange that it would
warn on the code I posted and never on, say,

for( unsigned int foo=0; foo < 5; foo++ );

since foo < 5 should be the same signed/unsigned comparison that it
complains about on the code I posted.

Apparently you just found the limit of that compiler's intelligence when it
comes to analyzing situations like this. In this last example the signed value
is an integral-constant expression and its value is known at compile time. The
compiler can immediately see that the value is positive and that's it is safe to
perform the comparison in unsigned context (as the language requires).

In the original case the value of the expression depended on a non-constant
boolean value, which means that the compiler could not immediately predict the
actual signed value at compile time. Of course, if it could analyze it a bit
deeper, it'd see either that 'foo' is always 'false' or that the two possible
results '1' and '2' are both positive, which means that there was no problem in
that case as well. But this compiler simply doesn't do this type of deeper
analysis. It is, once again, a pure QoI issue.

If it interests you, you might also want to try this

const bool foo=false; // <- note the 'const'
for( unsigned int bar=0; bar < (foo?1:2); bar++ ) {
bar=42;

and see what happens in this case.
 
C

Christopher Benson-Manica

Andrey Tarasevich said:
Language specification does not define situations when warnings should (or
should not) be issued. Warnings are implementation-dependent. And they are
largely a QoI issue.

Yes, I'm aware of that; I have, however, learnt not to trust
everything this particular C++ implementation tells me.
 
C

Christopher Benson-Manica

Andrey Tarasevich said:
If it interests you, you might also want to try this
const bool foo=false; // <- note the 'const'
for( unsigned int bar=0; bar < (foo?1:2); bar++ ) {
bar=42;
and see what happens in this case.

It did interest me, and the compiler accepted it silently. Thanks for
the insight.
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top