2012-02-11 9 views
9

He intentado articular esto en google, pero no he podido encontrar nada útil que lo describa. Aquí está el código:bracket y sintaxis macro en c

struct Segdesc gdt[] = 
{ 
    // 0x0 - unused (always faults -- for trapping NULL far pointers) 
    SEG_NULL, 

    // 0x8 - kernel code segment 
    [GD_KT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 0), 

    // 0x10 - kernel data segment 
    [GD_KD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 0), 

    // 0x18 - user code segment 
    [GD_UT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 3), 

    // 0x20 - user data segment 
    [GD_UD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 3), 

    // 0x28 - tss, initialized in trap_init_percpu() 
    [GD_TSS0 >> 3] = SEG_NULL 
}; 

Puede alguien explicar el significado de tener soportes sin una matriz o puntero delante de ellos ??

Respuesta

5

Esta sintaxis oscura se denomina inicializador designado y le permite omitir elementos al crear un conjunto de matriz.

Tome un vistazo a este programa:

#include <stdio.h> 
int a[] = { 
    1, [2]=3, [5]=7 
}; 
int main() { 
    int i; 
    for(i=0;i!=sizeof(a)/sizeof(int);i++) 
     printf("a[%d] = %d\n", i, a[i]); 
    return 0; 
} 

Se utiliza la misma sintaxis para omitir los elementos 1, 3 y 4 de la matriz a.

Esto es lo que este programa imprime:

a[0] = 1 
a[1] = 0 
a[2] = 3 
a[3] = 0 
a[4] = 0 
a[5] = 7 

Su programa hace lo mismo, pero se inicializa una matriz de estructuras, y el cálculo de los índices en su conjunto agregado mediante desplazamientos de bit de las constantes de tiempo de compilación. Puede encontrar los valores de estos índices en los comentarios (0x08, 0x10, 0x18, 0x20 y 0x28).

+0

Los inicializadores designados son una de las características nuevas más útiles de C99. –

0

En C, el operador [] y * pueden traducir a lo mismo al definir. pero, al asignar espacio, tienen una sintaxis diferente.

por ejemplo: a [1] y * (a + 1) son idénticos cuando se trata de una matriz de caracteres.

+0

Ok, pero eso de ninguna manera responde a la pregunta. – Dan

+0

Después de mirar las otras respuestas, ¿todavía crees que este "en este momento sea el que responda la pregunta"? –

6

Esto se llama designated initializer. Es una característica C99. Es útil al definir matrices que son en su mayoría ceros, con algunos valores en índices específicos.

ejemplos Cribbing fuera de la página GCC:

int a[6] = { [4] = 29, [2] = 15 }; 

es equivalente a

int a[6] = { 0, 0, 15, 0, 29, 0 }; 

"inicializador designado" también se refiere a la capacidad para inicializar estructuras de una manera análoga:

struct point p = { .y = yvalue, .x = xvalue }; 
1

Creo que esta sintaxis se introdujo en C99, aunque en un breve google surv ey, no puedo encontrar nada definitivo. En cualquier caso, en dialectos C antiguos, si desea inicializar explícitamente, por ejemplo, el tercer elemento de una matriz, debe enumerar explícitamente ceros para los elementos anteriores.Es decir,

int foo[4] = { 0, 0, 0, 42 }; // the 42 is arbitrary 

En C moderna, puede entrar en este lugar:

int foo[4] = { [3] = 42 }; 

La sintaxis es un poco oscura, pero la intuición, creo, es que lo que está haciendo es aproximadamente el tiempo de compilación-equivalente de:

int foo[4]; 
foo[3] = 42; 

a grandes rasgos, una vez más, el código de ejemplo es equivalente al

struct Segdesc gdt[(GD_TSS0 >> 3) + 1]; 
gdt[0] = SEG_NULL; 
gdt[GD_KT >> 3] = ...; 
... 
gdt[GD_TSS0 >> 3 ] = ...; 

La ventaja de esta sintaxis es que puede inicializar de forma más concisa una matriz, sin tener que contar los elementos de la matriz para obtener los que desea establecer en los lugares correctos. Además, esta sintaxis se puede aplicar a las inicializaciones de arreglos estáticos.