6 ms·
Insidious C Behavior
- petercooper 15y agoThe problem outlined in this post is explained in chapter 2 of K&R. I sympathize with the author and I agree it's insidious but it's also a rudimentary and well known snag.
- zvrba 15y ago"Problem" 1 is also well-known behavior for people who actually bother to learn it properly. C being such small language, there is almost no excuse for not learning it properly if you deal with it daily. Also, some C compilers warn about signed/unsigned comparisons. Some background on the signedness problem: http://yarchive.net/comp/ansic_broken_unsigned.html http://yarchive.net/comp/ansic_broken_unsigned.html
- _delirium 15y agoThe 2nd behavior is useful in macros, which sometimes need to do compile-time string concatenation (that might even be why it exists?).
- thealistra 15y agoThanks to apple we have a compiler alternative, that actually helps with this problem. alistra@bialobrewy ~ % clang -Weverything 1.c 1.c:6:8: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare] if(-1 < x) ~~ ^ ~
- noodly 15y agogcc also has -Wsign-compare option that warns about such comparisons.
- greyfade 15y agoGCC prints a similar warning with `-Wall`
- thealistra 15y agoactually with -Wextra alistra@bialobrewy ~ % gcc -Wextra 1.c 1.c: In function ‘main’: 1.c:6:8: warning: comparison between signed and unsigned integer expressions alistra@bialobrewy ~ % gcc -Wall 1.c alistra@bialobrewy ~ %
- _delirium 15y agoYes, for some reason in gcc, -Wall enables -Wsign-compare in C++ mode, but not in C mode. Maybe too much existing C code uses those kinds of comparisons?
- thealistra 15y agoThe fact the code uses those kinds of comparisons, doesn't mean, that it uses it properly.
- calloc 15y agoIn example two there is no \0 that is being removed by the compiler to do the concatenation. In the C language this is perfectly valid: "Testing something" ": more"; "Testing something" ": more"; This is still only considered one string, whether there are newlines in between or not. The translation unit is from the last semicolon to the next semicolon (overly simplified), so the compiler see this: "Testing something"": more"; Now it sees that there is no operator between the two "strings" and simply makes them a single string.
- henkie 15y agoThe output of "Problem 1" can actually be "yes", depending on the architecture. -1 is "all bits set" on two's complement signed integers but that's not the only integer encoding in existence. If you want "all bits set", write ~0. That's exactly all bits set and defined behaviour you can rely on in a portable program as opposed to an implementation detail.