Knowing how exactly sequence points work might be an advanced topic, but I am not sure I'd hire a junior C/C++ programmer if he has not heard of sequence points. If somebody has, then he clearly won't do something like this code. I am not 100% sure in how they work either (haven't programmed C for 4 years), so I just avoid these kind of unnecessary complications in the code, if not for myself, then for the guy who co…
I am not 100% sure in how they work either (haven't programmed C for 4 years), so I just avoid these kind of unnecessary complications in the code Hear, hear. I am considered the "language lawyer" of my embedded group and often get asked questions about C minutiæ. It isn't uncommon that my answer is "I don't know how that works, because I would never write something that requires an answer to that". Modern compilers…
A glimpse of undefined behavior in C
31–40 of 67 posts
Re: A glimpse of undefined behavior in C
#32Earlier quoted context omitted.
Ok, so do any other compilers handle it differently?
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)
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
#33Re: A glimpse of undefined behavior in C
#34The way I learned that in C a long time ago was "post increment" was "post statement increment".
/* 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
If one looks at the assembly, it's clearly equivalent to: for (int i = 0; i
Incidently, the latter seems more readable.Re: A glimpse of undefined behavior in C
#35Why? What reason could there possibly be that such well known, gaping holes in the standard have persisted for all these years and multiple standard revisions? C90, C99, C11 and now C14... If performance or backward compatibility is a concern, surely an optional macro like __STDC_STRICT__ could be suggested in the standard with clear expectations that could be relied on.
That's a reasonable question. It's a shame this comment gets downvoted instead of the various people falling all over themselves to show off how smart they are by posting incorrect guesses about how undefined behavior doesn't matter. Here's a good article that addresses the question "Why have undefined behavior?" http://blog.regehr.org/archives/213 This one linking to the above is also worth reading: http://blog.llvm…
I always imagined undefined behaviour was there to avoid tying implementations' hands, by having the standard not mandate things that vary in practice. But it seems that people are assuming it's there to give compiler writers carte blanche to do whatever they like, and then point at the standard as justification. Given how much stuff could potentially be added to C to improve it, I don't know why people are spending all this time trying to figure out all the ways in which the letter of the law allows them to confuse the programmer.
See also somebody else's rant about strict aliasing: http://robertoconcerto.blogspot.co.uk/2010/10/strict-aliasin...
Re: A glimpse of undefined behavior in C
#36Isn't this actually called "implementation-defined" behaviour in the std rather than "undefined" behaviour? I generally get a segfault for undefined behaviors
Re: A glimpse of undefined behavior in C
#37Why? What reason could there possibly be that such well known, gaping holes in the standard have persisted for all these years and multiple standard revisions? C90, C99, C11 and now C14... If performance or backward compatibility is a concern, surely an optional macro like __STDC_STRICT__ could be suggested in the standard with clear expectations that could be relied on.
Re: A glimpse of undefined behavior in C
#38Lesson I took away: The ++ operator should be deprecated except when it's the only operation on that line.
Re: A glimpse of undefined behavior in C
#39The way I learned that in C a long time ago was "post increment" was "post statement increment".
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 differ…
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
#40The way I learned that in C a long time ago was "post increment" was "post statement increment".
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.
"0 0 1" is what I would expect from your code, and identifier a should end up as 2.