Apa arti [N… M] dalam penginisialisasi agregat C?

101

Dari sys.c baris 123:

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

sys_call_tableadalah penunjuk umum ke array, saya bisa melihatnya. Namun apa notasinya:

[0 ... __NR_syscalls-1]

Apa itu ...?


EDIT:
Saya belajar trik C lain di sini: #include <asm/unistd.h>akan diproses sebelumnya dan diganti dengan isinya dan ditugaskan ke [0 ... _NR_syscalls-1].

Amumu
sumber
2
Tidak, ini bukan penunjuk ke larik, ini larik penunjuk. Sebuah pointer ke sebuah array akan dideklarasikanvoid (*sys_call_table)[__NR_syscalls]
Patrick Schlüter
@tristopia Anda benar. Yang saya maksud adalah penunjuk ke array, mirip dengan char *argv[]. Tetap.
Amumu

Jawaban:

90

Ini adalah inisialisasi menggunakan Designated Initializers .

Inisialisasi berbasis rentang adalah ekstensi gnu gcc.

Untuk menginisialisasi berbagai elemen ke nilai yang sama, tulis [first ... last] = value. Ini adalah ekstensi GNU. Sebagai contoh,

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

Ini tidak portabel. Menyusun dengan -pedanticmemberi tahu Anda begitu.

Bagaimana cara kerjanya di sini?
Preprocessor menggantikan #include <asm/unistd.h>dengan konten aktualnya ( mendefinisikan berbagai jenis dan konstanta simbolik, dan mendeklarasikan fungsi lain-lain ) dalam konstruksi berbasis rentang, yang kemudian digunakan lebih lanjut untuk menginisialisasi array pointer.

Alok Save
sumber
Sepertinya ini tidak portabel. Apakah itu?
Ivaylo Strandjev
5
@ Mehrdad Apakah kompilator microsoft c mematuhi standar c99? Saya mengistirahatkan kasus saya di sini ... c99
Aftnix
3
@Mehrdad: Sebenarnya, hanya konstruksi berbasis rentang dari Penginisialisasi yang Ditunjuk yang merupakan ekstensi gcc. Penginisialisasi yang Ditunjuk sendiri diizinkan oleh standar C.
Alok Save
2
@Mehrdad: Maaf, saya tidak ingin menjadi bagian dari umpan api, niat saya hanya untuk mengklarifikasi detail halus yang menurut saya Anda salah paham.
Alok Save
2
@Mehrdad: Agar jelas, range konstruksinya hanya portabel untuk gcc (dan kompiler yang mengimplementasikan ekstensinya), dan penginisialisasi yang ditunjuk secara umum hanya portabel untuk kompiler yang mendukung C99 (atau setidaknya fitur khusus itu).
Keith Thompson