Когда {0}
это используется для инициализации объекта, что это значит? Я нигде не могу найти никаких ссылок {0}
, и из-за фигурных скобок поиск в Google не помогает.
Пример кода:
SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;
if(ShellExecuteEx(&sexi))
{
DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
if(wait == WAIT_OBJECT_0)
GetExitCodeProcess(sexi.hProcess, &returnCode);
}
Без этого приведенный выше код будет зависать во время выполнения.
Следует помнить, что этот метод не устанавливает нулевые байты заполнения. Например:
Это не то же самое, что:
В первом случае байты pad между c и i неинициализированы. Почему тебя это волнует? Ну, если вы сохраняете эти данные на диск или отправляете их по сети или что-то еще, у вас может быть проблема безопасности.
источник
Обратите внимание, что пустой инициализатор агрегата также работает:
источник
В ответ на вопрос, почему
ShellExecuteEx()
происходит сбой: в вашей структуреSHELLEXECUTEINFO
"sexi" много членов, и вы только инициализируете некоторые из них.Например, член
sexi.lpDirectory
может указывать куда угодно, ноShellExecuteEx()
все равно будет пытаться его использовать, поэтому вы получите нарушение доступа к памяти.Когда вы включаете строку:
перед остальными настройками структуры вы говорите компилятору обнулить все элементы структуры, прежде чем инициализировать те, которые вас интересуют. Он
ShellExecuteEx()
знает, что если онsexi.lpDirectory
равен нулю, он должен его игнорировать.источник
Я также использую его для инициализации строк, например.
источник
{0}
является допустимым инициализатором для любого (завершенного объекта) типа, как в C, так и в C ++. Это общая идиома, используемая для инициализации объекта в ноль (читайте дальше, чтобы увидеть, что это значит).Для скалярных типов (арифметических и указательных типов) фигурные скобки не нужны, но они явно разрешены. Цитируя проект N1570 стандарта ISO C, раздел 6.7.9:
Он инициализирует объект в ноль (
0
для целых чисел,0.0
для чисел с плавающей точкой, нулевой указатель для указателей).Для нескалярных типов (структуры, массивы, объединения)
{0}
указывает, что первый элемент объекта инициализируется нулем. Для структур, содержащих структуры, массивы структур и т. Д., Это применяется рекурсивно, поэтому первый скалярный элемент устанавливается в ноль, в зависимости от типа. Как и в любом инициализаторе, любые не указанные элементы устанавливаются в ноль.Промежуточные скобки (
{
,}
) могут быть опущены; например, оба они действительны и эквивалентны:вот почему вам не нужно писать, например,
{ { 0 } }
для типа, чей первый элемент не является скалярным.Итак, это:
это сокращенный способ инициализации
obj
в ноль, означающий, что каждый скалярный подобъектobj
имеет значение,0
если оно является целым числом,0.0
если оно с плавающей запятой, или нулевым указателем, если это указатель.Правила похожи на C ++.
В вашем конкретном случае, поскольку вы присваиваете значения
sexi.cbSize
и т. Д., Ясно, чтоSHELLEXECUTEINFO
это структура или тип класса (или, возможно, объединение, но, вероятно, нет), поэтому не все это применимо, но, как я уже сказал{ 0 }
, это распространенное явление. идиома, которая может быть использована в более общих ситуациях.Это не (обязательно) эквивалентно использованию
memset
для установки представления объекта равным нулю. Ни0.0
указатель с плавающей точкой, ни нулевой указатель не обязательно представляются как ноль со всеми битами, и{ 0 }
инициализатор не обязательно устанавливает байты заполнения в какое-либо конкретное значение. Однако на большинстве систем это может иметь такой же эффект.источник
{0}
не является допустимым инициализатором для объекта без принятия конструктора0
; ни для агрегата, чей первый элемент как таковой (или агрегат без элементов)Прошло некоторое время с тех пор, как я работал на c / c ++, но в IIRC такой же ярлык можно использовать и для массивов.
источник
Я всегда задавался вопросом, почему вы должны использовать что-то вроде
Вот тестовый пример, чтобы объяснить:
check.c
Я компилирую с
gcc -O2 -o check check.c
и затемreadelf -s check | sort -k 2
выводю таблицу символов с помощью (это с gcc 4.6.3 на Ubuntu 12.04.2 в системе x64). Выдержка:Важной частью здесь является то, что
my_zero_struct
после__bss_start
. Раздел «.bss» в программе на C - это раздел памяти, который устанавливается в ноль, прежде чемmain
вызывается, см. Википедию на .bss .Если вы измените код выше на:
Тогда полученный исполняемый файл «check» выглядит точно так же, по крайней мере, с компилятором gcc 4.6.3 в ubuntu 12.04.2;
my_zero_struct
все еще находится в.bss
разделе и , таким образом , он будет автоматически инициализируются нулем, перед темmain
называется.Подсказки в комментариях, что
memset
может инициализировать «полную» структуру, также не является улучшением, потому что.bss
раздел очищен полностью, что также означает, что «полная» структура установлена в ноль.Это может быть то , что стандарт языка C не говоря уже о каком - либо из этого, но в реальном компиляторе мир C Я никогда не видел другое поведение.
источник
Это синтетический сахар для инициализации всей вашей структуры пустыми / нулевыми / нулевыми значениями.
Длинная версия
Укороченная версия
Разве это не было намного проще?
Это также приятно, потому что:
ZeroMemory
источник
{0} - это анонимный массив, содержащий его элемент как 0.
Это используется для инициализации одного или всех элементов массива с 0.
например, int arr [8] = {0};
В этом случае все элементы arr будут инициализированы как 0.
источник
{0}
не является анонимным массивом Это даже не выражение. Это инициализатор.