2011-06-06 12 views
16

Aktualnie pracuję nad starszym kodem C++, pomyślnie skompilowanym z gcc 2.9.X.
Zostałem poproszony o przeniesienie tego starszego kodu do gcc 3.4.X. Większość błędów została łatwo naprawiona, ale ta konkretna zagadka mnie zastanawia.Jakie jest znaczenie podwójnych nawiasów klamrowych inicjujących C-struct?

Kontekst:

struct TMessage 
    { 
    THeader header; 
    TData data; 
    }; 

struct THeader 
    { 
    TEnum myEnum; 
    TBool validity; 
    }; 

co zostało zrobione:

const TMessage init = {{0}}; 

/* Later in the code ... */ 
TMessage message = init; 

Moje pytanie (s):
Jaki jest sens {{}} operatora? Czy inicjuje pierwsze pole (nagłówek) do binarnego 0? Czy inicjuje pierwsze pole pierwszej struktury (enum) do (literału) 0?

Pojawia się błąd 3.4.6 z jedną lub dwiema parami nawiasów klamrowych.

Jak ustawić strukturę do liczby 0 bez użycia memsetu?

Z góry dziękuję.

+0

Dlaczego przenosisz swój kod ze starej wersji gcc do innej starej wersji gcc? –

+0

Aby skompilować/połączyć/wykonać na innej platformie. –

+0

Nie wiem o C++. W C nie ma błędu (być może kompilator jest zbyt pomocny, by się pomylić) – pmg

Odpowiedz

18

To inicjalizuje wszystkie pola struktury POD 0.

Uzasadnienie:

const SomeStruct init = {Value}; 

Zainicjowanie pierwsze pole z SomeStruct do wartości, w pozostałej części struktury do zera (I zapomnieć sekcję średnia, ale jest tam gdzieś)

Zatem:

const SomeOtherStruct init = {{Value}}; 

Inicjuje pierwsze pole pierwszego pola struktury (gdzie pierwsze pole struktury samo jest strukturą POD) do wartości, a reszta pierwszego pola do zera, a reszta struktury do 0.

Dodatkowo, tylko nie działa, ponieważ C++ zabrania niejawna konwersja int do wyliczenia rodzajów, więc można zrobić:

const SomeOtherStruct init = {{TEnum(0)}}; 
+1

Mówisz więc, że "const TMessage init = {{myEnumFirstValue}};" zainicjowałoby moje wyliczenie, a następnie co drugie pole na 0? Kompiluje się pomyślnie, teraz martwię się o środowisko uruchomieniowe. dzięki i tak! –

+3

Odpowiednia sekcja standardu to 8.5.1.7: * Jeśli na liście znajduje się mniej inicjalizatorów niż członków w agregacie, to każdy element nie jawnie zainicjowany zostanie zainicjowany wartością. * –

+0

Co oznacza ostatnia część? _są wartością-zainicjalizowane_: przez kompilator? –

1

Można go potraktować jako tablicę wielowymiarową (jeśli to pomaga). Następnie resetujesz dwa wymiary do 0 za pomocą tego polecenia. Działa to od (zakładam), że wartości wewnątrz struktury mogą przyjmować 0 jako wartość.

+0

Dzięki! Brakowało mi tego, że każde ** inne ** zostało zainicjowane na 0. –

3
  • pierwsze szelki dla struct TMessage
  • drugi klamra jest struct THeader
  • zero dosłowny jest TEnum myEnum

W tym przypadku są inicjalizacji TEnum z int0, który jest incompatible conversion.

Więc trzeba dodać odlewania tak:

const TMessage init = {{TEnum(0)}}; 

w C/C++, jeśli partially initialized struktura lub array (tylko niektóre z pierwszych Pola/elementów), reszta zostanie zainicjowany przez default constructor (która jest zerową inicjalizacją dla typów pierwotnych). Błąd kompilacji wystąpi, jeśli nie ma domyślnego konstruktora lub jeśli konstruktor zostanie zadeklarowany jako private.

+1

Nie jest prawdą, że reszta będzie zawsze inicjowana do zera. Jak napisałem w komentarzu do odpowiedzi @ Autopulated, będą one * zainicjowane wartością *. Na przykład, jeśli jeden z członków jest typu klasy z konstruktorem domyślnym, wówczas ten konstruktor zostanie wywołany. –

+0

@ Space_C0wb0y: Poprawiam się. Edytowałem swoją odpowiedź – dragon135

Powiązane problemy