2013-03-26 51 views
6

我在gcc下使用默认C语言。C使用现有的常量变量初始化const结构成员

我的代码:

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 }, 
}; 

错误:

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

如果我将omCopyBytes1更改为上述行中实际设置的值,代码编译得很好。我究竟做错了什么?

回答

5

不能使用omCopyBytes1初始化pOpcodeTable[]阵列中的一员,因为omCopyBytes1是运行时间常数,不是编译时间常数的变量。 C中的聚合初始化器必须是编译时常量,这就是为什么你的文章中的代码不能编译的原因。

作为一个变量,omCopyBytes1在内存中有自己的位置,它被初始化为一组项目。您可以通过指针使用这些变量,像这样:

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

或者,你可以把它的预处理器常数:

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

如果以这种方式定义的,omCopyBytes1将不再是一个变量:这将是一个预处理器定义,在编译器完成之前消失。我会建议不要使用预处理器方法,但如果你必须这样做,它就在那里。

+0

是否需要使用常量表达式来初始化C99中的所有聚合?在C99标准的6.7.8节中我没有看到这样的内容(静态存储持续时间的对象除外)。 – jamesdlin 2013-03-26 10:35:02

0

在C中,静态存储持续时间对象的初始值设定项必须为常量表达式。 A const限定变量不是常量表达式。

+0

当然,你并不是说所有的*初始化符都必须是常量表达式,除非你声称'int x = rand();'是非法的。 – jamesdlin 2013-03-26 10:41:30

+0

谢谢..修正。 – 2013-03-26 13:29:57