0

I want to declare a char array in a struct and initialize it when it is declared. I compiled it on g++ and VS2010 compilers. g++ could compile the following code but VS2010 couldn't. VS2010 has error. From C++ primer, const static type data could be initialized when it is declared in a struct/class. But when I use it for the OPName array, both compilers reports errors. I can only use const on g++ to achieve that. Why does it happen? What is the valid way to initialize array variables, like my example (i.e., char array), when they are declared in a struct/class?

Here is the code (.c file):

typedef struct OPMap {

const char OPName[27][6] = {"SW", "LW", // 2
                    "J", "BEQ", "BNE", "BGEZ", "BGTZ", "BLEZ", "BLTZ", // 7
                    "ADDI", "ADDIU", // 2
                    "BREAK", // 1
                    "SLT", "SLTI", "SLTU", // 3
                    "SLL", "SRL", "SRA", // 3
                    "SUB", "SUBU", "ADD", "ADDU", // 4
                    "AND", "OR", "XOR", "NOR", // 4
                    "NOP"}; // 1

unsigned int op[8][8];
unsigned int op_TLB[4][8];
unsigned int op_R[8][8];
const unsigned int NOP = 0x00000000;

OPMap() {
    //......
}

} Map;
David Yaw
  • 27,383
  • 4
  • 60
  • 93
Zizhao
  • 259
  • 3
  • 13
  • you can't initialize a typedef. If it's a const char lookup table why don't just implement as a separate array? – phuclv Sep 08 '14 at 03:49
  • you say `const static` is allowedm but you are not using static. – AShelly Sep 08 '14 at 03:52
  • with *typedef* you declare a type (or more like an alias), not a definition. you need to separate those two things. – AndersK Sep 08 '14 at 04:04
  • @Claptrap `typedef struct Foo { /* stuff */ } Bar;` is legal, although we can argue about whether it is good style or not – M.M Sep 08 '14 at 04:08
  • @MattMcNabb i am referring to `typedef struct OPMap { const char OPName[27][6] = {"SW", "LW", ` ... – AndersK Sep 08 '14 at 04:10
  • @Claptrap yes, I abbreviate the contents of the struct definition to `/* stuff */` to make it more obvious what is going on. You can define a struct and also define a typedef-name for it, in the same declaration. – M.M Sep 08 '14 at 04:11
  • @MattMcNabb ok got it, you are right, it just looks terrible. – AndersK Sep 08 '14 at 04:12
  • Do you think which is the best way to declare static a long char array in a struct? – Zizhao Sep 08 '14 at 13:16

2 Answers2

0

Before C++11, having an initializer for a data member in the class definition is only legal if the member is static const and also a non-struct, non-array (e.g. int or double). VS2010 does not comply with C++11 so you get that error.

For the code to work prior to C++11 you should change to:

static const char OPName[27][6];

and then in one of your .cpp files (i.e. not a header file) have:

static const char OPMap::OPName[27][6] = {"SW", "LW", // 2
                "J", "BEQ", "BNE", "BGEZ", "BGTZ", "BLEZ", "BLTZ", // 7
                "ADDI", "ADDIU", // 2
                "BREAK", // 1
                "SLT", "SLTI", "SLTU", // 3
                "SLL", "SRL", "SRA", // 3
                "SUB", "SUBU", "ADD", "ADDU", // 4
                "AND", "OR", "XOR", "NOR", // 4
                "NOP"}; // 1

In C++11 you can have this table in the class definition by adding in static constexpr .

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thanks for your answer. And How do you think my initialization of the const OPName works on g++? It is not a const static. – Zizhao Sep 08 '14 at 13:01
  • You will be using g++ either in c++11 mode, or with GNU extensions – M.M Sep 08 '14 at 20:53
0

There are multiple points here, the first one is that the rules are very different between C++98 and C++11. C++11 allows most in-class initialisation.

Supposing we are talking about C++98: When you write static const int x = 3; in your class, the compiler "sometimes" accept it, that is when it can simply remove all reference to MyClass::x and substitute the value, just like #defines. However if you try to use x in anyway other than a const expression, you will get error. For example if you have a line stating:

const int *px = &MyClass::x;

It won't work because now the compiler needs to assign a place in memory for x, and not just substitute the value as before. Now you will have to define it in a cpp file, i.e

const int MyClass::x = 3;

And of course, this only work for integral types. So in C++98, initialising class members are done in constructors, for instance variables, and by defining them in a cpp file, for static members. The in-class static const int x = 3; is just a shortcut that works "sometimes".

check out Defining static members in C++

Community
  • 1
  • 1