【问题标题】:C initialize const struct member with existing const variableC用现有的常量变量初始化常量结构成员
【发布时间】:2013-03-15 16:37:39
【问题描述】:

我在 gcc 下使用默认 C。

我的代码:

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 更改为上一行中实际设置的值,则代码可以正常编译。我做错了什么?

【问题讨论】:

    标签: c struct constants


    【解决方案1】:

    在 C 中,静态存储对象的初始值设定项必须是常量表达式const-qualified 变量不是常量表达式。

    【讨论】:

    • 当然你不是说 all 初始化器必须是常量表达式,除非你声称像 int x = rand(); 这样的东西是非法的。
    【解决方案2】:

    您不能使用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 将不再是变量:它将是在编译器完成之前消失的预处理器定义。我建议不要使用预处理器方法,但如果你必须这样做,它就在那里。

    【讨论】:

    • 在 C99 中初始化所有聚合真的需要常量表达式吗?我在 C99 标准的第 6.7.8 节中没有看到任何内容(静态存储持续时间的对象除外)。
    猜你喜欢
    • 2012-08-18
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多