This code: #include <iostream> struct s{ s(bool& bb) : i(0), b(bb), j(0) {} int i; bool& b; int j; };
bool f(s s1, s s2, s s3, int k) { s3.b = true; return false; } int main() { bool bz = false; s sz(bz); sz.b |= f(sz, sz, sz, 3); std::cerr << sz.b << "\n";; return 0; } prints this: s3:~/ootbc$ g++ foo.cc s3:~/ootbc$ a.out 0 It appears that "a |= f()" is being compiled as if it were the same as "a = a | F", with the compiler free to order the evaluation of a and f() in "a | f()" in any way it pleases. The order is exposed when f() has a side effect on a. However, my understanding of "a |= f()" is that it must be evaluated as if it were: bool& c = a; bool d = f(); operator|=(c, d) That is, the first argument to "|=" is a reference, not a value. Thus, both arguments (the reference and the function call) must be evaluated *before* "|=" is called and the reference will have already seen the side effect before "|=. -- Summary: Loses reference during update Product: gcc Version: 4.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: igodard at pacbell dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45437