News for hackers. Stuff that matters.
Re:What Every C Programmer Should Know About Undefined Behav... by CamperBob on Saturday May 14, 2011 @07:00PM (#2548780)
What would possess someone to write

  if (i < 0 || buffer+i-128 >= buffer)
   
... instead of

  if ((i < 0) || (i >= sizeof(buffer))

?
Re:What Every C Programmer Should Know About Undefined Behav... by kjksf on Saturday May 14, 2011 @07:24PM (#2548838)
That's not the right way of looking at this.

Instead, consider it from the point of view of probability.

Even if probability of any single programmer writing an exceedingly stupid piece of code is vanishingly small, the number of programmers writing new code daily is so big, that mistakes of vanishingly small probability end up being quite common indeed.

To given a real example: consider that Apple undoubtably employs only the finest programmers for their OS group and yet every iOS release is jailbroken quite quickly due to a piece of code which had a security bug.

Even within a much smaller scope of a single application, all web browser from Microsoft, Apple, Mozilla (and sometimes Google) are regularly compromised via security bugs despite huge investments from all those companies into security.

Toss in the fact that many programmers actually like doing things in unnecessarily clever or novel ways and inevitably the clever code is more likely to be buggy than boring code.

Bugs and crappy code is a statistical certainty, especially in languages like C and C++ that give you so many ways to shoot yourself in the foot.

Re:What Every C Programmer Should Know About Undefined Behav... by jws on Saturday May 14, 2011 @07:33PM (#2548852)
Many of the strange things that happen in C language edge cases come about from macro expansion or code generation.

Unrelated to the issue, but the superfluous parenthesis added in the second example are interesting. I think every C coder has a level of comfort with the 15 sets in the operator precedence rules, and beyond that they throw parenthesis at it. I'm fine with the rules until I use a <<, >>, &, ^, or |[1]. Then I drag out the parenthesis.

[1] I swear the positions of the ones I named are placed alphabetically rather than in relation to their mathematical function.

Re:What Every C Programmer Should Know About Undefined Behav... by gsg on Saturday May 14, 2011 @08:06PM (#2548915)
& and | have the wrong precedence because in primordial C they were both either short-circuiting boolean or bitwise depending on context.

:(

Re:What Every C Programmer Should Know About Undefined Behav... by defen on Saturday May 14, 2011 @07:08PM (#2548798)
Working within the "contrived example" framework, it would have made a little more sense if buffer were a pointer rather an array, in which case you wouldn't be able to use "sizeof".
Re:What Every C Programmer Should Know About Undefined Behav... by leif on Saturday May 14, 2011 @10:54PM (#2549178)
If it were not an array, the "undefined behavior" wouldn't come into effect. If it were a pointer, it would not have been eliminate (I'm pretty sure).
Re:What Every C Programmer Should Know About Undefined Behav... by iam on Sunday May 15, 2011 @03:24AM (#2549518)
Precisely. This optimization is possible because according to ANSI C, a variable is allowed to point to an address anywhere within an object, or at most one (sizeof) past an object. Anything else is undefined behavior (what they refer to as as "illegal pointer" in the post).

Therefore, buffer through buffer+1 would be valid pointers, but unless they can prove that i-128 is <=1 they can safely assume that the final pointer can be more than 1 past the buffer.

If it was just a pointer (not an array) they could do the same analysis if the pointer was mallocced right then in the same function with a constant size. More likely though, the pointer would be a function argument and then they would not know where the object boundaries were without doing interprocedural analysis (which I assume is outside of the scope of this post) and some other additional propagation (so technically within the C99 spec, but I doubt you would see an optimization that actually would do that).

Re:What Every C Programmer Should Know About Undefined Behav... by nonzero on Saturday May 14, 2011 @07:09PM (#2548802)
My thoughts exactly. I figured maybe there was some other crap in the ... that necessitated the convoluted 2nd part of the || statement, but I couldn't think of anything that would.
Re:What Every C Programmer Should Know About Undefined Behav... by Someone on Sunday May 15, 2011 @04:33AM (#2549603)
I would guess there are two answers:

- macro expansions

- the author took an example from a larger function and simplified it into a minimal test case. For example, there might be a

    #define BUFSIZE 128;
    ...
    j = buffer+i;
    ...
    if( (i < 0) || (i-BUFSIZE >= buffer))
Still weird (i - BUFSIZE could underflow), but more believable.
Re:What Every C Programmer Should Know About Undefined Behav... by sonoffett on Saturday May 14, 2011 @11:49PM (#2549257)
The OP has since changed the article but IIRC `buffer` was an array of `int`s, in which case the `sizeof` operator would return 512. Generally you'd want `(i >= sizeof(buffer)/sizeof(buffer[0]))`.