Skip to content
Prev 5860 / 21312 Next

[Bioc-devel] evaluation of C post-increments changed in GCC 4.8.2

Hi, Robert. C++ is my area so I can't speak as knowledgeably about C, 
but in this case I believe the cause is the same. I think the reason it 
feels like the postincrement evaluation order has been changed without 
warning is the code relied on 'undefined behavior'.

Often, in C-based languages 'undefined behavior' categorizes things a 
standardization committee identified as something that, for performance 
reasons, made more sense to rely on programmers to program around.

In the unsequenced modification and access case, according to the 
standard the compiler is free to evaluate the subexpressions in *any 
order*, the idea being the compiler will identify the most performant order.

Consider:
a[i] = i++;

This does three things
1) get array element a[i]
2) increment i
3) assign 2) to 1)

The only guarantee is 3) happens after 1) and 2), but 1) and 2) can 
happen in any order.

As you correctly identified, the way to avoid undefined behavior is to 
break the modification and access into separate full expressions. The 
simplest way to make a full expression is to put a semicolon after it!

A related place this comes up is in evaluating arguments for a function 
call.

Consider:
f(g(), h());

The only guarantee is that g() and h() will be evaluated before f is 
called. But what if g() and h() each have side effects on shared data? 
It's up to you to tell the compiler, for example, to first do g(), 
*then* do h() with:
int gres = g();
int hres = h();
f(gres, hres);

I confirm that using your test file gcc 4.6.3 indeed warns about 
unsequenced shenanigans with -Wall 'warning: operation on ?p? may be 
undefined [-Wsequence-point]'. I would add it's also a good idea during 
the development cycle to use -Wextra and -pedantic flags. (You can read 
about them here: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)
On Thu 12 Jun 2014 08:45:39 AM PDT, Robert Castelo wrote: