Co oznacza [N… M] w inicjalizatorach agregacji C?

101

Z linii sys.c 123:

void *sys_call_table[__NR_syscalls] = 
{
    [0 ... __NR_syscalls-1] = sys_ni_syscall,
#include <asm/unistd.h>
};

sys_call_tablejest ogólnym wskaźnikiem do tablic, widzę to. Jednak jaka jest notacja:

[0 ... __NR_syscalls-1]

Co to jest ...?


EDYCJA:
Nauczyłem się tutaj innej sztuczki C: #include <asm/unistd.h>zostanie wstępnie przetworzona i zastąpiona zawartością i przypisana do [0 ... _NR_syscalls-1].

Amumu
źródło
2
Nie, to nie jest wskaźnik do tablicy, to tablica wskaźników. Wskaźnik do tablicy zostałby zadeklarowanyvoid (*sys_call_table)[__NR_syscalls]
Patrick Schlüter
@tristopia masz rację. Miałem na myśli wskaźnik do tablic, podobny do char *argv[]. Naprawiony.
Amumu,

Odpowiedzi:

90

Jest to inicjalizacja przy użyciu wyznaczonych inicjatorów .

Inicjalizacja oparta na zakresie jest rozszerzeniem gnu gcc.

Aby zainicjować zakres elementów do tej samej wartości, napisz [first ... last] = value. To jest rozszerzenie GNU. Na przykład,

 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

Nie jest przenośny. Kompilując z -pedanticz, powiedz ci to.

Jak to działa?
Preprocesor zastępuje #include <asm/unistd.h>swoją rzeczywistą zawartość ( definiuje różne symboliczne stałe i typy oraz deklaruje różne funkcje ) w konstrukcji opartej na zakresie, które są następnie używane do inicjalizacji tablicy wskaźników.

Alok Save
źródło
Wygląda na to, że nie jest to przenośne. Jest?
Ivaylo Strandjev
5
@Mehrdad Czy kompilator Microsoft C jest zgodny ze standardem C99? Odpoczywam tutaj ... c99
Aftnix,
3
@Mehrdad: Właściwie tylko konstrukcja oparta na zakresie desygnowanych inicjatorów jest rozszerzeniem gcc, a same wyznaczone inicjatory są dozwolone przez standard C.
Alok Save
2
@Mehrdad: Przepraszam, nie chcę być częścią żadnej przynęty na płomienie, moim zamiarem było jedynie wyjaśnienie subtelnego szczegółu, który myślałem, że źle zrozumiałeś.
Alok Zapisz
2
@Mehrdad: Aby było jasne, konstrukcja zakresu jest przenośna tylko dla gcc (i kompilatorów, które implementują jego rozszerzenia), a wyznaczone inicjatory w ogólności są przenośne tylko dla kompilatorów obsługujących C99 (lub przynajmniej tę konkretną funkcję).
Keith Thompson,