Given the type
struct S
{
int x;
};
and two functions
S* f()
{
const auto x = new S[1] { { 42 } };
return x;
}
S* g()
{
const auto x = new S[1];
x[0] = {42};
return x;
}
one would think that f
and g
behave identical. According to this answerf
should perform an aggregate initialization on x
which would result in identical behavior. Looking at the assembly of clang and gcc this seems to be true and both f
and g
generate the exact same assembly.
However, msvc doesn't feel like doing it, I guess. The assembly of msvc for g
is similar to clang and gcc, but for f
it just seems to ignore the initializer altogether:
S * f(void) PROC ; f, COMDAT
mov ecx, 4
jmp void * operator new[](unsigned __int64) ; operator new[]
S * f(void) ENDP ; f
S * g(void) PROC ; g, COMDAT
$LN4:
sub rsp, 40 ; 00000028H
mov ecx, 4
call void * operator new[](unsigned __int64) ; operator new[]
mov DWORD PTR [rax], 42 ; 0000002aH
add rsp, 40 ; 00000028H
ret 0
S * g(void) ENDP ; g
Curiously, if we replace S
with int
msvc performs the initialization, but also adds some additional instructions (which I don't understand, maybe someone can shine a light on that as well).
int * f(void) PROC ; f, COMDAT
$LN6:
sub rsp, 40 ; 00000028H
mov ecx, 4
call void * operator new[](unsigned __int64) ; operator new[]
test rax, rax
je SHORT $LN3@f
mov DWORD PTR [rax], 42 ; 0000002aH
add rsp, 40 ; 00000028H
ret 0
$LN3@f:
add rsp, 40 ; 00000028H
ret 0
int * f(void) ENDP ; f
Here is a full example.
What is the standard conforming behavior in this case? And what are those additional assembly instructions in f
doing (if we replace S
with int
)?
Edit
Bug has been reported and can be tracked here.