2013-03-26 19 views
6

Używam domyślnego C pod gcc.C zainicjować element const struct z istniejącą zmienną stałą

mój kod:

typedef struct _OpcodeEntry OpcodeEntry; 

//

struct _OpcodeEntry 
{ 
    unsigned char uOpcode; 
    OpcodeMetadata pMetadata; 
}; 

//

const OpcodeMetadata omCopyBytes1 = { 1, 1, 0, 0, 0, 0, &CopyBytes }; 

const OpcodeEntry pOpcodeTable[] = 
{ 
    { 0x0, omCopyBytes1 }, 
}; 

Błędy:

error: initializer element is not constant 
error: (near initialization for 'pOpcodeTable[0].pMetadata') 

Jeśli zmienię omCopyBytes1 na to, co faktycznie jest ustawione w powyższym wierszu, kod kompiluje poprawnie. Co ja robię źle?

Odpowiedz

5

Nie można użyć omCopyBytes1, aby zainicjować element tablicy pOpcodeTable[], ponieważ omCopyBytes1 jest zmienną, która jest stałą czasu wykonywania, a nie stałą czasu kompilacji. Agregowane inicjalizatory w C muszą być stałymi w czasie kompilacji, dlatego kod z twojego wpisu nie kompiluje się.

Jako zmienna, omCopyBytes1 ma własne miejsce w pamięci, które jest inicjowane do tablicy elementów. Można użyć takiej zmiennej przez wskaźnik, jak to:

struct _OpcodeEntry { 
    unsigned char uOpcode; 
    const OpcodeMetadata *pMetadata; 
}; 
... 
const OpcodeEntry pOpcodeTable[] = { 
    { 0x0, &omCopyBytes1 }, // This should work 
}; 

Alternatywnie, można dokonać jej stałą preprocesora:

#define omCopyBytes1 { 1, 1, 0, 0, 0, 0, &CopyBytes } 

Jeśli zdefiniowany w ten sposób, omCopyBytes1 nie będzie już być zmienną : byłaby to definicja preprocesora, która znika przed wykonaniem kompilatora. Polecam wbrew metodzie preprocesora, ale jest na wszelki wypadek, jeśli musisz to zrobić.

+0

Czy rzeczywiście potrzebne są wyrażenia stałe do zainicjowania wszystkich agregatów w C99? Nic nie widzę w sekcji 6.7.8 standardu C99, mówiąc tak (poza przedmiotami o statycznym czasie przechowywania). – jamesdlin

0

In C, inicjatory dla obiektów statycznego czasu przechowywania muszą być wyrażeń stałych. Zmodyfikowana zmienna nie jest wyrażeniem stałym.

+0

Z pewnością nie znaczysz, że * wszyscy * inicjatorzy muszą być stałymi wyrażeniami, chyba że twierdzisz, że coś w rodzaju 'int x = rand();' jest nielegalne. – jamesdlin

+0

Dzięki. Naprawiono. –

Powiązane problemy