Почему компилятор бросает это предупреждение: «Отсутствует инициализатор»? Не инициализирована ли структура?

Я создаю какой-то интерфейс для программы. Для запуска программы я использую вызов CreateProcess() , который, среди прочего, получает указатель на структуру STARTUPINFO . Для инициализации структуры, которую я использовал:

 STARTUPINFO startupInfo = {0}; // Or even '\0'. startupInfo.cb = sizeof(startupInfo); 

При компиляции программы с GCC, позволяющей этим наборам предупреждений -Wall -Wextra это дает мне предупреждение, говорящее, что отсутствует -Wall -Wextra инициализатор, указывающий на первую строку.

 warning: missing initializer warning: (near initialization for 'startupInfo.lpReserved') 

Поэтому я закончил:

 STARTUPINFO startupInfo; memset(&startupInfo, 0, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); 

И таким образом компилятор не дает никаких предупреждений. Вопрос в том, в чем разница между этими способами инициализации структуры? Используя первый метод, не инициализируется ли структура? Какой из них вы бы порекомендовали?

По моему мнению, GCC просто чересчур параноик – по какой-то веской причине, но тогда, конечно, верно, что сторонники GCC знают намного больше о нюансах C, которые я делаю.

См. Эту небольшую дискуссию о проблеме в списке рассылки GCC:

Итог, хотя – инициализация структуры с помощью всего лишь {0} будет фактически нулевой инициализацией всего.

В стандарте C99 говорится следующее в 6.7.8 / 21 «Инициализация – семантика»:

Если в списке, заключенном в скобках, меньше инициализаторов, чем в элементе или элементах совокупности или меньше символов в строковом литерале, используемом для инициализации массива с известным размером, чем в массиве, остальная часть совокупности должна неявно инициализируется тем же, что и объекты, имеющие статическую продолжительность хранения.

C90 говорит в то же самое в 6.5.7 с немного другой формулировкой (другими словами, C99 не добавил сюда что-то новое).

Также обратите внимание, что в C ++ это было расширено, так что пустой набор фигурных скобок « {} » выполнил инициализацию значения для объекта, потому что были ситуации (например, шаблоны), когда вы даже не знали, что члены или сколько членов тип может иметь. Таким образом, это не только хорошая практика, но и необходимость иногда иметь список инициализаторов, который короче, чем количество членов, которые могут иметь объекты.

Это можно легко установить для GCC в программах на C ++, инициализируя структуру как

 STARTUPINFO startupInfo = STARTUPINFO(); 
  • просто сделал именно это несколько дней назад

Вы запросили как можно больше предупреждений, используя -Wall -Wextra.

В этом случае вы получаете предупреждение, в котором говорится, что вы не указали все поля, что совершенно верно, но могло быть непреднамеренным.

Вы можете подавить это предупреждение, добавив инициализаторы -Wno-missing-field

На этой веб-странице подробно обсуждается основная проблема: http://ex-parrot.com/~chris/random/initialise.html

В качестве рабочего решения мое текущее решение заключается в выборочном подавлении этого предупреждения:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-field-initializers" STARTUPINFO startupInfo = {0}; #pragma clang diagnostic pop 

К сожалению, это работает только в clang и, похоже, не работает в GCC.

В C ++ вы можете использовать boost::initialized_value чтобы избавиться от этого предупреждения. У меня есть предупреждения для boost ; поэтому я не знаю, приведет ли это к другим предупреждениям в вашем случае. Таким образом, вам не нужно отключать предупреждение.

Пример:

 T bla = boost::initialized_value;