kvanbere
kvanbere

Reputation: 3352

C initialize const struct member with existing const variable

I'm using default C under gcc.

My code:

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

Errors:

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

If I change omCopyBytes1 to what it's actually set to in the above line, the code compiles fine. What am I doing wrong?

Upvotes: 7

Views: 18248

Answers (2)

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215627

In C, initializers for objects of static storage duration must be constant expressions. A const-qualified variable is not a constant expression.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727097

You cannot use omCopyBytes1 to initialize a member of pOpcodeTable[] array, because omCopyBytes1 is a variable that is run-time constant, not a compile-time constant. Aggregate initializers in C must be compile-time constants, that's why the code from your post does not compile.

As a variable, omCopyBytes1 has its own place in memory, which is initialized to an array of items. You can use such variable by a pointer, like this:

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

Alternatively, you can make it a preprocessor constant:

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

If defined in this way, the omCopyBytes1 would no longer be a variable: it would be a preprocessor definition that vanishes before the compiler is done. I would recommend against the preprocessor method, but it's there in case you must do it.

Upvotes: 7

Related Questions