Я смотрел на этот маленький фрагмент:
#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
}
НКУ а также лязг правильно выводить 0
но MSVC2013 обновление 3 выхода 1
,
Я читаю 5.3.4/17
относительно new
а также новый инициализатор но не смог найти ничего оправдывающего поведение MSVC.
Я что-то пропустил? Это известная проблема?
Редактировать: я прилагаю дамп памяти из MSVC и сгенерированный код сборки (выпуск x64)
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)
Это ошибка компилятора MS VC ++. Согласно стандарту C ++ (5.3.4 New)
17 Новое выражение, которое создает объект типа T, инициализирует этот объект следующим образом:
— если новый инициализатор опущен, объект инициализируется по умолчанию (8.5); если инициализация не выполняется, объект имеет неопределенное значение.
— В противном случае новый инициализатор интерпретируется в соответствии с правилами инициализации 8.5 для прямой инициализации.
И далее (8.5.1 Агрегаты)
7 Если в списке меньше инициализаторов-предложений, чем элементов в агрегате, то каждый элемент, который не был явно инициализирован, должен быть инициализирован из своего фигурного или равного инициализатора или, если нет фигурного или равного инициализатора, из пустой список инициализаторов (8.5.4).
и (8.5.4 инициализация списка)
— В противном случае, если в списке инициализатора нет элементов, объект инициализируется значением
и наконец (8.5 инициализаторов)
8 Инициализировать значение объекта типа T означает
…
— если T является типом массива, то каждый элемент инициализируется значением;
— иначе объект инициализируется нулями.
Таким образом, все элементы массива должны быть инициализированы нулями.