2016-08-02 8 views
7

I był przez następnego kodu, który zgłasza char * tablicę w C w niestandardowym sposób:Stosując deklarację niestandardowe tablicy, w C

/* Message Type description array */ 
    char *msgType[M_LAST_MSG] = 
    {  
     [M_INIT_MSG]  "Init", 
     [M_RESET_MSG] "Serdes Reset" 
    }; 

M_INIT_MSG, M_RESET_MSG i M_LAST_MSG są wyliczenia z odpowiednimi wartościami 0, 1 i 2. Zgodnie z formalnymi dokumentami C, zmienne w tej tablicy są ciągami (literałami), więc jaki jest cel używania tych wyliczeń w ten sposób i czy istnieje jakaś dokumentacja do jej utworzenia?

Kompilowany z kompilatorem ARM gccgcc-arm-none-eabi.

+3

Prawdopodobnie brakuje ci '=' w swoich inicjalizacjach: '[M_INIT_MSG] =" Init "' itp. Wyszukaj * wyznaczone inicjatory *. –

+1

Nie, nie tęskniłem za tym. Odpowiedź edytowana. – user2162550

+1

Mówienie o standardowym/niestandardowym, a następnie łączenie z rozszerzeniem gcc prawdopodobnie nie jest dobrym pomysłem ... Ale co na dołączonej stronie nie jest jasne? Jest to przestarzałe rozszerzenie gcc, czy nawet czytałeś stronę? Ze strony: "_ Alternatywna składnia tego, co było przestarzałe, odkąd GCC 2.5, ale GCC nadal akceptuje, to napisanie" [index] "przed wartością elementu, bez" = "._" – Olaf

Odpowiedz

6

Ta składnia pozwala zainicjować konkretne elementy tablicy przez indeks. Można użyć wartości int lub enum, aby określić, który element tablicy ma zostać zainicjowany. W ten sposób przypisane wartości nie muszą być kolejne.

Jeśli na przykład trzeba było to:

int x[5] = { [2] 3, [4] 7 }; 

byłoby równoważne to:

int x[5] = { 0, 0, 3, 0, 7 }; 

W powyższym przykładzie wartości enum określić, które elementy 0 i 1 z tablicy są Zainicjowano na "Init" i "Serdes Reset".

Z sekcji 6.7.8 części C99 standard:

lista

18 Każde oznaczenie zaczyna swój opis z bieżącego obiektu związanego z najbliższej okolicy nawiasów pary. Każda pozycja na liście desygnatorów (w kolejności) określa określonego elementu jej bieżącego obiektu i zmienia bieżący obiekt dla następnego oznacznika (jeśli taki jest) na członka. Bieżący obiekt, który pojawia się na końcu listy desygnatorów, to obiekt podrzędny, który ma zostać zainicjowany przez następujący inicjator.

33 Przykład 9 tablic mogą być inicjowane odpowiadają elementów wyliczenia przez wykorzystaniem oznaczników:

enum { member_one, member_two }; 
const char *nm[] = { 
    [member_two] = "member two", 
    [member_one] = "member one", 
}; 

Edycja:

że składnia od normy zawiera = chwilę Przykład OP nie. Składnia bez = jest najwyraźniej starą składnią obsługiwaną przez GCC. Kompilacja przykład OP daje następujące ostrzeżenie:

ostrzeżenie: nieaktualne wykorzystania wyznaczonego inicjatora bez '='

The GCC documentation stwierdza co następuje:

Alternatywną składnię tego, że ma były przestarzałe, ponieważ GCC 2.5, ale GCC nadal akceptuje, to napisać "[indeks]" przed wartością elementu, bez "=".

+2

Składnia bez znaku równości jest specyficzna dla GNU. – a3f

+2

To nie odpowiada, dlaczego działa składnia w pytaniu. OP najwyraźniej jest świadomy standardowej składni. – Olaf

3

To jest GNU extension. Został standaryzowany w C99 z nieco inną składnią, a mianowicie znakiem równości między [indeksem] a wartością i brakiem możliwości określenia zakresu indeksów. Są one nazywane wyznaczonymi inicjalizatorami.

średnia

C przedstawia przykład prawdopodobnie najbardziej powszechnym użyciu, zapewnia opis tekstowy dla teksty stałe:

33 Przykład 9 Macierze można zainicjować odpowiadać elementów wyliczenie za pomocą oznacznik :

enum { member_one,   member_two }; 
const char *nm[] =   { 
    [member_two]   = "member two", 
    [member_one]   = "member one", 
}; 

To pozwala nawet ładne rzeczy jak

PRZYKŁAD 11 Oznaczniki mogą być wykorzystane w celu zapewnienia wyraźnej inicjalizacji gdy ozdób listy inicjująca może być źle zrozumiany:

struct { int a[3], b; } w[] = 
    { [0].a = {1}, [1].a[0] = 2 }; 
+0

Pamiętasz link do dokumentacji? – CinCout

+0

@CinCout, [szkic C11] (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) '6.7.9 Inicjalizacja' – Kamiccolo

+0

Brakowało mi znaku równości . Poprawiłem odpowiedź. – a3f

Powiązane problemy