0

I have been making a Roguelike recently, and have been getting compile errors with this specific code:

typedef const char* string;

typedef struct {
string name;
string desc;
int dice;
int sides;
} weapon;

typedef struct {
string name;
string desc;
int dice;
int sides;
} armor;

typedef struct {
string name;
char icon;
int x;
int y;
weapon wep;
armor arm;
int hp;
int maxhp;
} creature;

This is in a header file.

Another file defines external variables:

extern creature monsters[MAX_MONSTERS];
extern creature level_cre[MAX_LEVELCRE];
extern weapon weapons[MAX_WEAPONS];
extern armor armors[MAX_ARMORS];

In the file that defines weapon and armor arrays:

weapon weapons[MAX_WEAPONS] = {
    {"Sword", "A steel sword", 1, 6},
};

armor armors[MAX_ARMORS] = {
    {"Leather", "Leather armor", 1, 10},
};

And the part that is giving me an error:

creature monsters[MAX_MONSTERS] = {
    {"Skeleton", 's', 0, 0, weapons[0], armors[0], 100, 100},
    {"Orc", 'o', 0, 0, weapons[0], armors[0], 100, 100},
};

Running this gives me the error in the title, and after doing some research it appears to come from not defining constants properly. I am at a complete loss here as to what to do. Any help would be appreciated. :)

  • 2
    The error si very clear. `weapons[0]` etc. are not constant expressions. It also is a bad approach to copy the weapon data. Just set a pointer to the current weapon. – too honest for this site Feb 23 '16 at 23:55
  • And don't `typedef` pointers! That is error-prone6, makes your code harder to understand and makes e.g. pointers to `const` qualified objects impossible. – too honest for this site Feb 23 '16 at 23:57
  • [Error “initializer element is not constant” when trying to initialize variable with const](https://stackoverflow.com/questions/3025050/error-initializer-element-is-not-constant-when-trying-to-initialize-variable-w) – kaylum Feb 23 '16 at 23:58
  • Should they be? In the typedef they are not specified as const. Sorry, I am using this game as a learning experience for advanced C features. – user3295121 Feb 23 '16 at 23:58
  • I don't see any "advanced" C features (whatever you mean by that). But if you want to, you definitively add `const`-correctness to the list. A good idea is to first make up your mind and have a concept. One general principle in programming (not limited to C) is to avoid redundancies. – too honest for this site Feb 24 '16 at 00:00
  • Haha, just a word I use for stuff I don't understand. If I change the array to a const, should I also change the struct in the creature struct to be const as well? – user3295121 Feb 24 '16 at 00:03
  • If `weapons` and `armors` will not be changed, make them `const` – M.M Apr 19 '16 at 08:06

1 Answers1

0

ISO/IEC 9899:201x, Initialization, §4:

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

ISO/IEC 9899:201x, Constant expressions, §7:

More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:
— an arithmetic constant expression,
— a null pointer constant,
— an address constant, or
— an address constant for a complete object type plus or minus an integer constant expression.

weapons[0] and armors[0] are none of the above. But as Olaf suggested you can change to

weapon *wep;
armor *arm;
…
    {"Skeleton", 's', 0, 0, &weapons[0], &armors[0], 100, 100},
    {"Orc",      'o', 0, 0, &weapons[0], &armors[0], 100, 100},

- &weapons[0] and &armors[0] are address constants and thus usable in an initializer.

Armali
  • 18,255
  • 14
  • 57
  • 171