Consider the following program:
struct X {
bool b;
int y;
};
void f(int*);
bool test(X x) {
if (!x.b) {
return false;
}
f(&x.y);
return x.b;
}
It seems that the statement
return x.b;
does not get optimized to return true;
So my conclusion is, that the compiler must assume that f(int*)
could modify x.b
by doing this:
void f(int* p) {
bool* q = reinterpret_cast<bool*>(p - 1);
*q = false;
}
Is this implementation of f
actually valid C++? Or differently phrased, must the compiler always assume that the entire object may change when a pointer to a member is passed to an opaque function?
Compiler output with clang-x86 trunk (-O1) is this:
test(X): # @test(X)
push rax
mov qword ptr [rsp], rdi
test dil, dil
je .LBB0_1
lea rdi, [rsp + 4]
call f(int*)@PLT
cmp byte ptr [rsp], 0
setne al
pop rcx
ret
.LBB0_1:
xor eax, eax
pop rcx
ret
One interpretation I can come up with, is that the given definition of f
is valid C++ if I only ever call it like in the example above and so the compiler must assume that possibility.