First of all, you need to slightly modify your example so that it can be compiled. A function must have at least an execution path that returns a value.
A* getA(){ if(false) return NULL; A* p = new A(1,2,3);
Secondly, this is obviously undefined behavior, which means that everything can happen, but I think this answer will not satisfy you.
Thirdly, in Windows it works in debug mode, but if you compile in Release, it is not.
The Debug section compiles the following:
A* p = new A(1,2,3); 00021535 push 0Ch 00021537 call operator new (211FEh) 0002153C add esp,4 0002153F mov dword ptr [ebp-0E0h],eax 00021545 mov dword ptr [ebp-4],0 0002154C cmp dword ptr [ebp-0E0h],0 00021553 je getA+7Eh (2156Eh) 00021555 push 3 00021557 push 2 00021559 push 1 0002155B mov ecx,dword ptr [ebp-0E0h] 00021561 call A::A (21271h) 00021566 mov dword ptr [ebp-0F4h],eax 0002156C jmp getA+88h (21578h) 0002156E mov dword ptr [ebp-0F4h],0 00021578 mov eax,dword ptr [ebp-0F4h] 0002157E mov dword ptr [ebp-0ECh],eax 00021584 mov dword ptr [ebp-4],0FFFFFFFFh 0002158B mov ecx,dword ptr [ebp-0ECh] 00021591 mov dword ptr [ebp-14h],ecx
The second command, calling operator new
, goes into eax
pointer to the newly created instance.
A* a = getA(); 0010484E call getA (1012ADh) 00104853 mov dword ptr [a],eax
The calling context expects eax
to contain the return value, but it does not contain the last pointer allocated by new
, by the way, p
.
So why does this work.