News for hackers. Stuff that matters.
Re:A glimpse of undefined behavior in C by micro-ram on Saturday November 30, 2013 @03:02PM (#6824393)
The way I learned that in C a long time ago was "post increment" was "post statement increment".
Re:A glimpse of undefined behavior in C by ballard on Saturday November 30, 2013 @06:12PM (#6825105)
There was a popular myth way back in the 90's that preincrement was always faster than postincrement because the former could generate a temporary. As if this were the case:

    /* x++ */
    inline int postincrement(int *x) {
      int temp = *x;
      *x = *x + 1;
      return temp;
    }

    /* ++x */
    inline int preincrement(int *x) {
      *x = *x + 1;
      return *x;
    }

But in typical usage, where the expression value is not used, it doesn't make any difference:

    for (int i = 0; i < 10; ++i) {

If one looks at the assembly, it's clearly equivalent to:

    for (int i = 0; i < 10; i++) {

Incidently, the latter seems more readable.
Re:A glimpse of undefined behavior in C by ezy on Saturday November 30, 2013 @06:39PM (#6825209)
I always thought this "myth" was confined to C++ code (iterators) where there may in fact be code that does something analogous to what your "postincrement()" does.

Compilers are sometimes smart enough to remove the unnecessary operation in C++ (e.g. switch to ++x themselves), but I always use ++i for the same reason people simplify their usage of C in between sequence points --- it's an easy transformation, and why tempt fate?

Re:A glimpse of undefined behavior in C by nly on Saturday November 30, 2013 @07:20PM (#6825386)
The compiler can't necessarily optimise i++ away in C++, because the ++operator or the destructor of the temporary iterator object returned may have side effects. It's still not quite equivalent to ballards postincrement() though, because the C++ standard allows for that temporary copy operation to be optimised away
Re:A glimpse of undefined behavior in C by bookface on Saturday November 30, 2013 @07:00PM (#6825313)
I was actually asked in an interview at Google in 2011 whether pre- or postincrement was faster in a snippet of code where the expression's value wasn't used. When I said that I was pretty confident that the compiler would produce the same assembly in both cases, the interviewer insisted that pre- was faster based on the same logic you mentioned.

To her credit, she didn't penalize me for disagreeing with her and I still got the offer.

Re:A glimpse of undefined behavior in C by nilkn on Saturday November 30, 2013 @07:10PM (#6825357)
This is one of those things I've had in my head for years, and as a result of this I habitually use pre-increment in code, even in other languages. I think I haven't actually believed the "myth" myself, though, for quite a while.
Re:A glimpse of undefined behavior in C by jfoutz on Saturday November 30, 2013 @04:12PM (#6824640)
it's a little weirder though. int main(int argc, char argv) { int a = 0; printf("%i %i %i\n", a, a++, a++); }

will give "0 0 1" (gcc 4.2.1), the increment "shouldn't" happen until after the ; if you're going with post statement. I think your rule would expect "0 0 0" with a being 2 after the printf.

BUT! you get a warning, so that's nice.

Re:A glimpse of undefined behavior in C by jacquesgt on Saturday November 30, 2013 @05:45PM (#6825018)
The issue here is that the order of function argument evaluation is undefined. If the commas weren't inside of a function call, they would result in sequence points. So, this would be well defined:

   int a = 0, b, c;
   b = a++, c = a++;
But, there is no defined order in which to evaluate function arguments.
Re:A glimpse of undefined behavior in C by NAFV_P on Saturday November 30, 2013 @06:40PM (#6825215)
The example given in the article shows all the code, but your example involves a function so the code in question is hidden. The behaviour partially depends on how the function is written.

"0 0 1" is what I would expect from your code, and identifier a should end up as 2.

Re:A glimpse of undefined behavior in C by agumonkey on Saturday November 30, 2013 @04:12PM (#6824641)
I can't help but to put this in the same bag as javascript lack of block scope, exemplified in the famous for loops counter undesired effects.
Re:A glimpse of undefined behavior in C by dnautics on Saturday November 30, 2013 @03:06PM (#6824413)
exactly. This is precisely to spec; and I got the answer of 60 immediately on looking at the code.
Re:A glimpse of undefined behavior in C by haberman on Saturday November 30, 2013 @03:12PM (#6824435)
This is incorrect; it is undefined behavior according to the spec: http://www.reddit.com/r/programming/comments/1rrefp/a_glimps...
Re:A glimpse of undefined behavior in C by micro-ram on Saturday November 30, 2013 @03:17PM (#6824452)
Ok, so do any other compilers handle it differently?
Re:A glimpse of undefined behavior in C by quesera on Saturday November 30, 2013 @03:46PM (#6824547)
Yep.

Clang says:

  zsh% clang -o sequencepoints sequencepoints.c
  sequencepoints.c:7:18: warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
    int r = 1 * a[i++] + 2 * a[i++] + 3 * a[i++];
                   ^            ~~
  1 warning generated.
And prints:

  zsh% ./sequencepoints
  140
Re:A glimpse of undefined behavior in C by tedunangst on Saturday November 30, 2013 @03:43PM (#6824541)
Practically every new version of gcc adds a new optimization that recognizes some new form of undefined behavior and then rewrites your function to do whatever it wants.

Classic example: signed integer overflow. It worked for decades. Then one day it didn't.

If you want to know about this particular example: https://news.ycombinator.com/item?id=6824514 (not personally confirmed)

Re:A glimpse of undefined behavior in C by army on Saturday November 30, 2013 @05:55PM (#6825050)
That isn't really an accurate description of the issues: it's not the case that it was "working" and then "broken" by GCC maintainers. It's always been unsupported and not worked in specific situations, but for 99% of code it appeared to GCC users that it was supported. The signed integer overflow behaviour was never guaranteed by old versions of GCC, and code exploiting it would not always be compiled with the "expected" behaviour. It's just as the GCC optimizer has improved there are more circumstances when it does optimisations that hinge on the assumption.

Compiler users generally want something that "just works" and doesn't do anything unexpected, but in the case of a low-level language like C, doing away with undefined behavior essentially would mean pessimistically avoiding many optimisations on the 99%+ of straightforward, reasonable code out there in favor of not doing anything surprising on the remaining fraction of dubious code that depends on certain things happening in scenarios where behavior is undefined according to the C standard. There are languages that make that choice, but C isn't one of them.

Re:A glimpse of undefined behavior in C by tedunangst on Saturday November 30, 2013 @06:44PM (#6825242)
That is my point. De facto working code is not working code.

I have fixed feelings about the integer overflow issue because it's so easy to trigger, unlike triple post increment fake examples. And it usually results in a security problem. For very little benefit, IMO.

Re:A glimpse of undefined behavior in C by randyrand on Saturday November 30, 2013 @03:39PM (#6824524)
Exactly. De facto defined is usually just as important to consider as de jure.
Re:A glimpse of undefined behavior in C by dnautics on Saturday November 30, 2013 @04:46PM (#6824758)
ah, sorry, I'm stuck in C[whatever it was I learned in high school]