Reputation: 6414
I'd like to keep my keywords in a struct:
typedef const char* label;
const struct keywords_t
{
label init;
label moveUnit;
} keywords;
But I'd like to be able to check whether a keyword is valid with a for loop, so I tried to initialize the struct like this:
const label allowed_keywords[] =
{
"INIT",
"MOVE"
};
const struct keywords_t keywords =
{
allowed_keywords[0],
allowed_keywords[1]
};
This gives me an
error: initializer element is not constant
What am I doing wrong? The whole array is constant, though.
Upvotes: 0
Views: 102
Reputation: 19221
I might be the best resource for this, but both Arrays and Structs are simple memory mapping tools.
An array of char *
and a struct containing the same number of char *
should have the same memory structure and the same memory footprint.
So, in practice, all you need is to cast the array into the struct rather then anything else (this will also save you memory, although this is probably not so important).
i.e.
const label allowed_keywords[] =
{
"INIT",
"MOVE"
};
typedef const char* label;
const struct keywords_t
{
label init;
label moveUnit;
};
// struct keywords_t * keywords = (struct keywords_t *) allowed_keywords;
#define keywords ((struct keywords_t *) allowed_keywords)
A few things:
this needs to be tested.
I would avoid using the _t
for the struct keywords_t
, as _t
is reserved for POSIX types. I use _s
for structs and _pt
for pointers... but that's up to you.
Upvotes: 1
Reputation: 16047
In C const
variables are not constants, they are simply variables that cannot be changed. Thus their value cannot be used in constant expressions, like in struct initializer.
One work-around could be to use preprocessor defines for initializers:
#define KEYWORD_INIT "INIT"
#define KEYWORD_MOVE "MOVE"
const label allowed_keywords[] =
{
KEYWORD_INIT,
KEYWORD_MOVE
};
const struct keywords_t keywords =
{
KEYWORD_INIT,
KEYWORD_MOVE
};
Other approach could be to use combination of enumeration and array:
typedef enum {
KEYWORD_INIT,
KEYWORD_MOVE
} label;
const char * const keyword_strings[] = {
"INIT",
"MOVE"
};
const struct keywords_t keywords =
{
KEYWORD_INIT,
KEYWORD_MOVE
};
// Getting keyword string would be like this:
// keyword_strings[keywords.moveUnit]
Upvotes: 7