Was bedeutet [N… M] in C-Aggregat-Initialisierern?

101

Aus der sys.c- Zeile 123:

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

sys_call_tableist ein generischer Zeiger auf Arrays, das kann ich sehen. Was ist jedoch die Notation:

[0 ... __NR_syscalls-1]

Was ist das ...?


EDIT:
Ich habe hier einen weiteren C-Trick gelernt: #include <asm/unistd.h>Wird vorverarbeitet und durch seinen Inhalt ersetzt und zugewiesen [0 ... _NR_syscalls-1].

Amumu
quelle
2
Nein, es ist kein Zeiger auf ein Array, es ist ein Array von Zeigern. Ein Zeiger auf ein Array würde deklariertvoid (*sys_call_table)[__NR_syscalls]
Patrick Schlüter
@ Tristopia du hast recht. Was ich meinte, war ein Zeiger auf Arrays, ähnlich wie char *argv[]. Fest.
Amumu

Antworten:

90

Es handelt sich um eine Initialisierung mit Designated Initializers .

Die bereichsbasierte Initialisierung ist eine gnu gcc-Erweiterung.

Schreiben Sie, um einen Bereich von Elementen mit demselben Wert zu initialisieren [first ... last] = value. Dies ist eine GNU-Erweiterung. Beispielsweise,

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

Es ist nicht tragbar. Kompilieren mit -pedanticmit sag es dir.

Wie funktioniert das hier?
Der Präprozessor ersetzt #include <asm/unistd.h>durch seinen tatsächlichen Inhalt ( er definiert verschiedene symbolische Konstanten und Typen und deklariert verschiedene Funktionen ) im bereichsbasierten Konstrukt, die dann weiter zum Initialisieren des Array von Zeigern verwendet werden.

Alok Speichern
quelle
Es scheint, dass dies nicht tragbar ist. Ist ist?
Ivaylo Strandjev
5
@Mehrdad Entspricht der Microsoft C-Compiler dem C99-Standard? Ich ruhe meinen Fall hier aus ... c99
Aftnix
3
@Mehrdad: Tatsächlich ist nur das bereichsbasierte Konstrukt von Designated Initializers eine gcc-Erweiterung. Designated Initializers selbst sind nach dem C-Standard zulässig.
Alok Save
2
@Mehrdad: Entschuldigung, ich möchte nicht Teil eines Flammenköders sein, ich wollte nur ein subtiles Detail klären, von dem ich dachte, dass Sie es missverstanden haben.
Alok Save
2
@Mehrdad: Um klar zu sein, das Bereichskonstrukt ist nur für gcc (und Compiler, die seine Erweiterungen implementieren) portierbar, und bestimmte Initialisierer sind im Allgemeinen nur für Compiler portierbar, die C99 (oder zumindest diese bestimmte Funktion) unterstützen.
Keith Thompson