N
Nomen Nescio
BartC said:That's true; the value of -3000000000u on my 32-bit C is well-defined;
completely wrong, but well-defined according to the Standard.
Actually only lcc-win32, out of my handful of C compilers, bothers to tell
me that that expression has an overflow.
The 'whinings' were to do with being dependent on compiler options for
figuring why programs like this:
I asked about that before elsewhere, why can't/don't C compilers do a better
job of pointing out obvious problems, given various lints have been written
to do just that. It seems so obvious to me that logic should be included in
a compiler worthy of the name. I was told to go **** myself. I didn't, but I
understood I was treading on another UNIX golden calf so..
unsigned int a=4;
signed int b=-2;
printf("%u<%d = %d\n", a, b, a<b);
printf("%d<%d = %d\n", 4, b, 4<b);
printf("%u<%d = %d\n", a, -2, a<-2);
printf("%d<%d = %d\n", 4, -2, 4<-2);
(notice the integer literals, or constants, or whatever you like to call
them today, have been correctly displayed as signed values) produce output
like this:
4<-2 = 1
4<-2 = 0
4<-2 = 1
4<-2 = 0
You don't need to know any C, or any language, for it to raise eyebrows. And
as it happened, I had trouble getting any of my four compilers to give any
warning, until someone told me to try -Wextra on gcc.
I don't know any C but it did raise my eyebrows. Looking into this a little:
#include <stdio.h>
int main() {
unsigned int a = 4;
signed int b = -2;
printf("%u<%d = %d\n", a, b, a<b);
printf("%d<%d = %d\n", 4, b, 4<b);
printf("%u<%d = %d\n", a, -2, a<-2);
printf("%d<%d = %d\n", 4, -2, 4<-2);
}
Works like yours:
./bartc
4<-2 = 1
4<-2 = 0
4<-2 = 1
4<-2 = 0
Agreed, not very helpful. Now let's try:
Solaris lint, comes with the system:
lint bartc.c
(9) warning: suspicious comparison of unsigned with negative constant: op "<"
function returns value which is always ignored
printf
Got one and missed one.
Even better, this:
Splint 3.1.2 --- 23 Nov 2011
bartc.c: (in function main)
bartc.c:7:32: Operands of < have incompatible types (unsigned int, int): a < b
To ignore signs in type comparisons use +ignoresigns
bartc.c:7:32: Format argument 3 to printf (%d) expects int gets boolean: a < b
To make bool and int types equivalent, use +boolint.
bartc.c:7:20: Corresponding format code
bartc.c:8:32: Format argument 3 to printf (%d) expects int gets boolean: 4 < b
bartc.c:8:20: Corresponding format code
bartc.c:9:33: Operands of < have incompatible types (unsigned int, int): a < -2
bartc.c:9:33: Format argument 3 to printf (%d) expects int gets boolean: a < -2
bartc.c:9:20: Corresponding format code
bartc.c:10:33: Format argument 3 to printf (%d) expects int gets boolean:
4 < -2
bartc.c:10:20: Corresponding format code
bartc.c:11:2: Path with no return in function declared to return int
There is a path through a function declared to return a value on which there
is no return statement. This means the execution may fall through without
returning a meaningful result to the caller. (Use -noret to inhibit warning)
Finished checking --- 7 code warnings
Conclusions: C (again) fails the least-surprise test, which is least surprising
since it is a language that just happened in an environment where there was
no premium on doing things right but there was a premium on doing them cheap
and without giving any help to the programmer. Resources were tight and
small and ok was better than big and good. What's the excuse now, in the
21st century? Two thumbs up to splint, btw. Damn fine piece of code.
Any serious C coder probably should use some form of lint or even better, splint.
How much C does someone need to know, to complain about -1 being silently
converted to something like 4294967295?
I saw the problem and it is somewhat obvious (I write assembly code for
work) but that doesn't mean everybody gets it right all the time in a big
piece of code. The compiler should be more helpful. And lint should be built
in to every C compiler.
A lot of my 'whinings' are backed up by people who know the language
inside-out. And although nothing can be done because the Standard is always
right, and the language is apparently set in stone, at least discussion
about various pitfalls can increase awareness.
Yes, C sucks, so why use it? I saw pretty quickly discussing any
shortcomings of UNIX or Linux or C just creates a flamefest, no matter how
shitty or broken all that stuff is. When you start messing with peoples'
religion you're going to get your ass kicked. Although it's hard to say
which is preferable, a trip to the dentist or coding on x86, I guess x86
assembly is preferably to C. At least there aren't any surprises. Lots of
disappointment and gasps of horror, but not real surprises.