Reputation: 92942
Consider a small unit test case
struct A
{
virtual void func(){}
A& foo()
{
A *obj = reinterpret_cast<A*>(0xdeadbeef);
return *obj; //1
}
};
int main()
{
A obj = obj.foo();
}
At line 1
is it implementation defined/unspecified that the deference would not happen as we are returning by reference and the program would not crash if an explicit access to the pointed to object is not made?
I had argument with one of my colleagues wherein he mentioned that the compiler, in most cases, would optimize the dereference of obj
as we are returning it by reference and this code would not crash?
Thanks
Upvotes: 5
Views: 179
Reputation: 192
I disassemble the code in MS VC8.0, and find things more interesting:
006D48D6 mov dword ptr [ebp-8],ecx
A *obj = reinterpret_cast<A*>(0xdeadbeef);
006D48D9 mov dword ptr [obj],0DEADBEEFh
return *obj; //1
006D48E0 mov eax,dword ptr [obj] //2
}
006D48E3 mov esp,ebp
006D48E5 pop ebp
006D48E6 ret
//2 shows that just put the address of obj to the eax register as return value.
006D39FC lea ecx,[ebp-190h]
006D3A02 call A::foo (6A8C12h)
006D3A07 push eax //3
006D3A08 lea ecx,[ebp-190h]
006D3A0E call A::A (6B89BEh)
eax is 0xdeadbeef, and push to stack as temporary local variable does. Than we call the copy constructor(which is trivial) . All these actions are just pass the address(which is illegal but program do not care).Because the A struct does not have any member which is binded to specific object, and program will not try to find specific object by dereference if it doesn' t need.So this bomb have not been fired.
A *obj = reinterpret_cast<A*>(0xdeadbeef);
A tmp ;
temp = *obj;
Even this is OK because operator= is also pass by reference which in fact pass the address.If you add a member variable, it will fail because it will try to find and copy the member.
Upvotes: 4