Below are two common issues resulting in undefined behavior due to the sequence point rules:
a[i] = i++; //has a read and write between sequence points
i = i++;
The one I've seen recently was due to programmer's desire to save on class formatting time, completely wrong-headed:
class A
{
public:
...
const char* Format( const string& f ) const
{
fmt = Print( f, value );
return fmt.c_str();
}
operator const char* () const { return fmt.c_str(); }
private:
struct timeval value;
mutable string fmt;
};
A a( ... );
printf( "%s %s\n", a.Format( x ), a.Format( y );
The last line would either always print the same value for both formats (or crash the program since internal string would release the returned memory).
Another one is from some interview I had long ago:
void func( int x, int y, int z )
{
printf( "%d %d %d\n", x, y, z );
}
...
int i = 0;
func( i, ++i, i++ ); /* don't do this in real software :) */