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

Reply via email to