Style question: comparison between signed and unsigned?

Hartmut Niemann (niemann@cip.e-technik.uni-erlangen.de)
Fri, 26 Sep 1997 11:10:09 +0200 (MSZ)


>
> BTW, I agree that requiring many extra casts is a bad idea, because
> there's no way of telling if a cast is only intended to emphasize
> default semantics or if it should also twist the type compatibility.
Oh yes, there is. Have a look at what is written.
You never know whether a cast would be needed by a paranoid compiler,
but is automatic type conversion a good thing by itself??

Modula2 did not have it (AFAIK), and this made some strange
constructions necessary.
But I prefer having to think when writing the code to having to think
when I debug it.

What is worse: *reading* what the program is doing,
or having to *know* what gcc is going to do with it?
I learned in this thread that for
(i < sizeof(...))
the comparison will be signed.
I was surprised that this can be a trouble spot.

If it's ( (uint) i < sizeof(...) ) or
( i < (int) sizeof(...) )
one can *see* what is written (sure you can err and forget ()s on
a function call -- tough luck ). But you don't have to know or remember
or guess. This is why I prefer it.

How annoying do you find gcc's warning on
if (c=getc()) type
constructions? It suggests another pair of parentheses to stress the
assignment, but if you write
if ( (c=getc()) !=0 )
it will (even without -O) produce exactly the same assembler sequence,
it will not substract 0 from anything. And it will be far more readable
for people who are not familiar with this piece of code.
And gcc catches easily all meant-to-be compares when I have written
Pascal the day before ;-)

>>
>> I also note that gcc occasionally gets into the habit of encouraging
>> a certain syntax, e.g. the use of parentheses when mixing &&, ||,
>
>I'm told (long time ago) that some compilers had the precedence rules
>the wrong way around. So your software would behave wrong unexpectedly
>when compiled with one of those.
The practical subset of the precedence rules is: * and / precede + and -,
everything else gets (). Why worry if it is easily typed, does not cost
compile or run time and makes things easier to read? Why care whether
== precedes && or not?
(Remark: I had a projekt in MUMPS, which does evaluate even
1*4+2*3 to 18 ...)

Ansi C made a big improvement (IMHO) from old K&R C, and mostly *because*
it checks things easily overlooked. gcc goes (with -Wall) even further,
and I like it, because most of the time it shows me where I did not think
hard enough.
I would prefer writing (i < (int) sizeof(..)) and check whether gcc is
able to handle that without extra size_t-to-int conversion cycles
to not having gcc tell me that i and sizeof() don't mix cleanly.

Hartmut.