输入类型
struct S
{
int x;
};
和两个功能
S* f()
{
const auto x = new S[1] { { 42 } };
return x;
}
S* g()
{
const auto x = new S[1];
x[0] = {42};
return x;
}
人们会认为f
和g
的行为相同。根据{{3}},f
应该在x
上执行聚合初始化,这将导致相同的行为。查看clang和gcc的汇编,这似乎是正确的,f
和g
都生成完全相同的汇编。
但是,我想msvc不想这样做。 g
的msvc汇编类似于clang和gcc,但是对于f
来说,它似乎完全忽略了初始化程序:
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
奇怪的是,如果我们将S
替换为int
,则msvc会执行初始化,但还会添加一些其他指令(我不理解,也许有人也会对此有所启发)。
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
this answer是一个完整的例子。
在这种情况下,符合标准的行为是什么?在f
中执行的那些附加汇编指令还有什么(如果我们将S
替换为int
)?
错误已报告,可以Here进行跟踪。