Tworzę rodzaj nakładki na program. Do uruchomienia programu używam wywołania CreateProcess()
, które między innymi otrzymuje wskaźnik do STARTUPINFO
struktury. Aby zainicjować strukturę, którą robiłem:
STARTUPINFO startupInfo = {0}; // Or even '\0'.
startupInfo.cb = sizeof(startupInfo);
Podczas kompilowania programu z GCC włączającym te zestawy ostrzeżeń -Wall -Wextra
daje mi ostrzeżenie, że brakuje inicjalizatora wskazującego na pierwszą linię.
warning: missing initializer
warning: (near initialization for 'startupInfo.lpReserved')
Więc skończyło się na zrobieniu:
STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
W ten sposób kompilator nie daje żadnego ostrzeżenia. Pytanie brzmi, jaka jest różnica między tymi sposobami inicjalizacji struktury? Czy przy użyciu pierwszej metody struktura nie została zainicjowana? Który byś polecił?
struct struct_with_four_fields x = {1, 2, 3};
tylko 3 z 4 członków są inicjowane.{ 0 }
jest to powszechny i dobrze zdefiniowany idiom do inicjowania wszystkich elementów członkowskich do zera (zdefiniowany rekurencyjnie dla każdego elementu podrzędnego) - dlatego późniejsze wersje gcc zostały zmodyfikowane, aby nie ostrzegały o tym konkretnym przypadku.obj = {0};
w wiadomości, do której utworzyłeś łącze, jest nieprawidłowy w C i gcc 4.8.2 odrzuca go jako błąd składniowy. Jeśli kompilujesz jako C ++, pamiętaj, że jest to inny język, a gcc używa innego interfejsu; poprawki w kompilatorze C gcc mogą, ale nie muszą, dotyczyć g ++.Odpowiedzi:
GCC jest po prostu zbyt paranoikiem - moim zdaniem bez dobrego powodu, ale z pewnością prawdą jest, że opiekunowie GCC wiedzą o wiele więcej o niuansach C, które ja robię.
Zobacz ten mały wątek dyskusji na temat problemu na liście dyskusyjnej GCC:
Konkluzja jednak - inicjalizacja struktury po prostu
{0}
spowoduje zerową inicjalizację całości.Standard C99 mówi, co następuje w 6.7.8 / 21 „Inicjalizacja - sematyka”:
C90 mówi zasadniczo to samo w 6.5.7 z nieco innym sformułowaniem (innymi słowy, C99 nie dodał tutaj czegoś nowego).
Zwróć również uwagę, że w C ++ zostało to rozszerzone tak, że pusty zestaw nawiasów klamrowych „
{}
” wykonywałby inicjalizację wartości na obiekcie, ponieważ zdarzały się sytuacje (takie jak szablony), w których nawet nie wiedziałbyś, kim są członkowie lub ilu członków typ może mieć. Jest to więc nie tylko dobra praktyka, ale czasami konieczne jest posiadanie listy inicjalizującej, która jest krótsza niż liczba elementów członkowskich, które może mieć obiekt.źródło
-Wno-missing-field-initializers
i-Wno-missing-braces
żeby GGC przestało narzekać, że stawiam= {0};
na moje konstrukcje. Czy ktoś wie, czy wyłączenie tego ostrzeżenia spowoduje pominięcie ostrzeżeń dotyczących innych rzeczy niż= {0};
konstrukcje?mingw32-g++.exe (GCC) 4.7.2
i otrzymuję to ostrzeżenie w powyższym idiomie (nawet w dokładnym przypadkuSTARTUPINFO
).{}
lub{0}
inicjatorów w moich klas C ++ /Można to łatwo naprawić dla GCC w programach C ++, inicjując strukturę jako
źródło
Poprosiłeś o jak najwięcej ostrzeżeń za pomocą
-Wall -Wextra
.W takim przypadku otrzymasz ostrzeżenie informujące, że nie określiłeś wszystkich pól, co jest całkowicie poprawne, ale mogło być niezamierzone.
Możesz pominąć to ostrzeżenie, dodając
-Wno-missing-field-initializers
źródło
Ta strona internetowa szczegółowo omawia podstawowy problem: http://ex-parrot.com/~chris/random/initialise.html
Aby obejść ten problem, moim obecnym rozwiązaniem jest selektywne pomijanie tego ostrzeżenia:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-field-initializers" STARTUPINFO startupInfo = {0}; #pragma clang diagnostic pop
Niestety, to działa tylko w clang i nie wydaje się działać w GCC.
źródło
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
zaakceptowane przez kompilator GCC 4.2.1, ale nic nie robię. niepewny co do nowych wersji gcc#pragma clang diagnostic ignored "-Wmissing-field-initializers"
. Powinieneś prawdopodobnie sprawdzić, czy tak jest.W C ++ możesz
boost::initialized_value
pozbyć się tego ostrzeżenia. Mam wyłączone ostrzeżenia dlaboost
; więc nie wiem, czy spowodowałoby to jakiekolwiek inne ostrzeżenia w twoim przypadku. W ten sposób nie musisz wyłączać ostrzeżenia.Przykład:
źródło