oh, well, it looks like the difference here is in the type of the variable. i.e., the following code generates different output depending on the #if on top with gcc (no C++ involved). I am so surprised that I have to ask: is this really expected behavior ? #include <stdio.h> #include <stdbool.h> #if 1 #define TYPE char #define TYPE_T 1 #define TYPE_F 0 #else #define TYPE bool #define TYPE_T true #define TYPE_F false #endif static TYPE g_error = TYPE_F; TYPE foo (void) { g_error |= TYPE_T; return TYPE_F; } int main (int argc, char *argv[]) { printf ("g_error=%d\n", g_error); g_error |= foo (); printf ("g_error=%d\n", g_error); return 0; } On Wed, Sep 30, 2009 at 9:31 AM, Mathieu Lacage <mathieu.lacage@xxxxxxxxx> wrote: > hi, > > While debugging a piece of code which was not setting a boolean > correctly to true, I stumbled upon this (reduced) testcase: > > #include <iostream> > > static bool g_error = false; > > bool foo (void) > { > g_error |= true; > return false; > } > > int main (int argc, char *argv[]) > { > std::cout << g_error << std::endl; > g_error |= foo (); > std::cout << g_error << std::endl; > > return 0; > } > > This code prints: 0 + 0 but the following C program: > > #include <stdio.h> > > static int g_error = 0; > > int foo (void) > { > g_error |= 1; > return 0; > } > > int main (int argc, char *argv[]) > { > printf ("g_error=%d\n", g_error); > g_error |= foo (); > printf ("g_error=%d\n", g_error); > > return 0; > } > > does print 0 + 1 (both tests without optimizations on gcc 4.3.2 fc10 i386) > > So, here, the C and C++ frontends do not agree on when g_error is read > relative to the call to foo. Is this expected (i.e., is this a bug in > one of them) ? > > If this is expected, are there recommendations about how this kind of > code should be written to avoid such un-expected differing behaviors ? > (Yes, it's pretty trivial to store the return value of foo and then to > or it separately, but I wonder what is the best way to make sure that > this kind of error creeps in). > > Mathieu > -- > Mathieu Lacage <mathieu.lacage@xxxxxxxxx> > -- Mathieu Lacage <mathieu.lacage@xxxxxxxxx>