

Insidious C Behavior - aklein
http://blog.adamdklein.com/?p=554

======
zvrba
"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>

------
petercooper
The 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.

------
thealistra
Thanks 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)
                 ~~ ^ ~

~~~
greyfade
GCC prints a similar warning with `-Wall`

~~~
thealistra
actually 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
Yes, 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
The fact the code uses those kinds of comparisons, doesn't mean, that it uses
it properly.

------
calloc
In 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.

------
_delirium
The 2nd behavior is useful in macros, which sometimes need to do compile-time
string concatenation (that might even be why it exists?).

------
henkie
The 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.

