Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22155

Dynamic array initialization behavior of msvc differs from gcc and clang

$
0
0

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.


Viewing all articles
Browse latest Browse all 22155

Trending Articles