Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a static const char* in your header file?

Tags:

c++

constants

I'd like to define a constant char* in my header file for my .cpp file to use. So I've tried this:

private:     static const char *SOMETHING = "sommething"; 

Which brings me with the following compiler error:

error C2864: 'SomeClass::SOMETHING' : only static const integral data members can be initialized within a class

I'm new to C++. What is going on here? Why is this illegal? And how can you do it alternatively?

like image 379
Mark Avatar asked Oct 28 '09 18:10

Mark


People also ask

How do you declare a constant character?

const char *YourClass::SOMETHING = "something"; C++ standard, 9.4. 2/4: If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression.

What is const char * const *?

const char* const says that the pointer can point to a constant char and value of int pointed by this pointer cannot be changed. And we cannot change the value of pointer as well it is now constant and it cannot point to another constant char.

What is static const char?

const char* is a pointer to a constant char, meaning the char in question can't be modified. char* const is a constant pointer to a char, meaning the char can be modified, but the pointer can not (e.g. you can't make it point somewhere else).

What does static const do in C++?

“static const” is basically a combination of static(a storage specifier) and const(a type qualifier). The static determines the lifetime and visibility/accessibility of the variable.


2 Answers

NB : this has changed since C++11, read other answers too

You need to define static variables in a translation unit, unless they are of integral types.

In your header:

private:     static const char *SOMETHING;     static const int MyInt = 8; // would be ok 

In the .cpp file:

const char *YourClass::SOMETHING = "something"; 

C++ standard, 9.4.2/4:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression. In that case, the member can appear in integral constant expressions within its scope. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

like image 183
KeatsPeeks Avatar answered Sep 18 '22 20:09

KeatsPeeks


To answer the OP's question about why it is only allowed with integral types.

When an object is used as an lvalue (i.e. as something that has address in storage), it has to satisfy the "one definition rule" (ODR), i.e it has to be defined in one and only one translation unit. The compiler cannot and will not decide which translation unit to define that object in. This is your responsibility. By defining that object somewhere you are not just defining it, you are actually telling the compiler that you want to define it here, in this specific translation unit.

Meanwhile, in C++ language integral constants have special status. They can form integral constant expressions (ICEs). In ICEs integral constants are used as ordinary values, not as objects (i.e. it is not relevant whether such integral value has address in the storage or not). In fact, ICEs are evaluated at compile time. In order to facilitate such a use of integral constants their values have to be visible globally. And the constant itself don't really need an actual place in the storage. Because of this integral constants received special treatment: it was allowed to include their initializers in the header file, and the requirement to provide a definition was relaxed (first de facto, then de jure).

Other constant types has no such properties. Other constant types are virtually always used as lvalues (or at least can't participate in ICEs or anything similar to ICE), meaning that they require a definition. The rest follows.

like image 27
AnT Avatar answered Sep 19 '22 20:09

AnT