Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 819
kvanbere Avatar asked Mar 26 '13 01:03

kvanbere


People also ask

How do you initialize a const member variable?

To initialize the const value using constructor, we have to use the initialize list. This initializer list is used to initialize the data member of a class. The list of members, that will be initialized, will be present after the constructor after colon. members will be separated using comma.

Can struct members be const?

You can const individual members of a struct. Declaring an entire instance of a struct with a const qualifier is the same as creating a special-purpose copy of the struct with all members specified as const .

Do const variables need to be initialized?

A constant variable must be initialized at its declaration. To declare a constant variable in C++, the keyword const is written before the variable's data type. Constant variables can be declared for any data types, such as int , double , char , or string .

Can const be applied on structure objects?

'const' as the word constant itself indicates means unmodifiable. This can be applied to variable of any data type. struct being a user defined data type, it applies to the the variables of any struct as well. Once initialized, the value of the const variables cannot be modified.


1 Answers

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.

like image 159
Sergey Kalinichenko Avatar answered Oct 03 '22 01:10

Sergey Kalinichenko