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