Hello
While inspecting some compiler-generated code, I was surprised to find a call to operator new(unsigned int, void*). This is the placement form of operator new which simply returns the pointer argument and which cannot be overridden by the application. I never thought I'd see an actual call to it. In particular, the following trivial code snippet:
#include <new> char buffer[100]; int* test() { return ::new ( (void*) buffer ) int(42); }
produces similarly simple x86 output using gcc (gcc -O3 -S):
__Z4testv: LFB16: .cfi_startproc movl $42, _buffer movl $_buffer, %eax ret .cfi_endproc
but leads to much more complicated output using the C6000 compiler 7.4.16 (cl6x.exe -mv64+ --abi=eabi -O3 -k --rtti --opt_for_speed=5 --include_path="%PATH_TO_CCS_INC%")
_Z4testv: ;** --------------------------------------------------------------------------* MVKL .S2 buffer,B4 MVKH .S2 buffer,B4 STW .D2T2 B3,*SP--(8) ; |6| || CALLP .S2 _ZnwjPv,B3 || MVK .L1 0x4,A4 ; |7| $C$RL0: ; CALL OCCURS {_ZnwjPv} {0} ; |7| ;** --------------------------------------------------------------------------* MVK .S1 42,A3 ; |7| || MV .L1 A4,A0 ; |7| [ A0] STW .D1T1 A3,*A0 ; |7| LDW .D2T2 *++SP(8),B3 ; |8| [!A0] ZERO .L1 A0 ; |7| MV .L1 A0,A4 ; |7| NOP 2 RETNOP .S2 B3,5 ; |8| ; BRANCH OCCURS {B3} ; |8|
Curiously, the TI compiler explicitly calls operator new (unsigned int, void*) (requiring stack space and saving registers) and even ignores the fact that the return value is guaranteed to be the second argument.
Admittedly, none of that is wrong, but as you typically use placement new in more performance-critical areas, it would be a lot nicer if the compiler just removed the call completely.
Maybe you can consider implementing that optimization for a future compiler release, given that it should be a rather trivial to add.
Markus