Marco A.
Marco A.

Reputation: 43662

MSVC2013 and new array brace-initialization issue

I've been looking at this small snippet:

#include <iostream>
#include <cstring>

int main()
{
    char const *a = "my string";
    size_t len = strlen(a);
    char *b = new char[len + 1]{0};

    char *zeroes = new char[strlen(a) + 1];
    memset(zeroes, 0, strlen(a) + 1);

    std::cout << memcmp(b, zeroes, strlen(a) + 1); // 0 expected
}

gcc and clang correctly output 0 but MSVC2013 Update 3 outputs 1.

I read 5.3.4/17 regarding new and new-initializer but couldn't find anything justifying MSVC's behavior.

Am I missing something? Is this a known issue?


Edit: I'm attaching the memory dump from MSVC and the generated assembly code (x64 release)

enter image description here

int main()
{
000007F676571270  push        rbx  
000007F676571272  sub         rsp,20h  
    char const *a = "my string";
    size_t len = strlen(a);
    char *b = new char[len + 1]{0};
000007F676571276  mov         ecx,0Ah  
000007F67657127B  call        operator new[] (07F676571704h)  
000007F676571280  mov         rbx,rax  
000007F676571283  test        rax,rax  
000007F676571286  je          main+1Dh (07F67657128Dh)  
000007F676571288  mov         byte ptr [rax],0  // zero the first one out
000007F67657128B  jmp         main+1Fh (07F67657128Fh)  
000007F67657128D  xor         ebx,ebx  

    char *zeroes = new char[strlen(a) + 1];
000007F67657128F  mov         ecx,0Ah  
000007F676571294  call        operator new[] (07F676571704h)  

Upvotes: 3

Views: 185

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

It is a bug of MS VC++ compiler. According to the C++ Standard (5.3.4 New)

17 A new-expression that creates an object of type T initializes that object as follows:

— If the new-initializer is omitted, the object is default-initialized (8.5); if no initialization is performed, the object has indeterminate value.

— Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for directinitialization.

And further (8.5.1 Aggregates)

7 If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equalinitializer, from an empty initializer list (8.5.4).

and (8.5.4 List-initialization)

— Otherwise, if the initializer list has no elements, the object is value-initialized

and at last (8.5 Initializers)

8 To value-initialize an object of type T means

...

— if T is an array type, then each element is value-initialized; — otherwise, the object is zero-initialized.

So all elements of the array shall be zero initialized.

Upvotes: 2

Related Questions