Why I cannot initialize a static const char* in the header file? In my code I have in my Class header:
static const char* xml_ID_TAG;
and in the cpp:
const char* Class::xml_ID_TAG = "id";
The xml_ID_TAG variable contains the attribute string of an XML document. Since it's static, const, primitive type (char*), etc... I can't figure out why the compiler forbid to write something like:
static const char* xml_ID_TAG = "id";
I'm using MSVC2013 compiler, giving for the example above the error: "Error: a member with an in-class initializer must be const"
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.
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).
A static data member can be of any type except for void or void qualified with const or volatile . You cannot declare a static data member as mutable . You can only have one definition of a static member in a program.
A "character constant" is formed by enclosing a single character from the representable character set within single quotation marks (' ').
Generally speaking you must define your static members in precisely one translation unit, and the language helps to enforce this by prohibiting you from writing an initialiser for such a member inside the surrounding class definition:
struct T
{
static int x = 42;
// ^ error: ISO C++ forbids in-class initialization of
// non-const static member 'T::x'
};
However, a special exception is made for constants, for convenience:
struct T
{
static const int x = 42;
// ^ OK
};
Note that in most cases you still need to define the constant (in your .cpp file would be the best place):
const int T::x;
[C++11: 9.4.2/3]:]
If a non-volatileconst static
data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.19). Astatic
data member of literal type can be declared in the class definition with theconstexpr
specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. [ Note: In both these cases, the member may appear in constant expressions. —end note ] The member shall still be defined in a namespace scope if it is odr-used (3.2) in the program and the namespace scope definition shall not contain an initializer.
Now, your member is not an int
and even a const char* const
is not of an "integral type":
struct T
{
static const char* const str = "hi";
// ^ error: 'constexpr' needed for in-class initialization of
// static data member 'const char* const T::str' of non-integral type
};
but it is of a "literal type"; the upshot for you is that if you write it like this:
static constexpr const char* const xml_ID_TAG = "id";
// ^^^^^^^^^ ^^^^^
you should be okay. (Note that you will still need to define it, until C++17.)
This probably makes more sense anyway: why would you want to change the pointer?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With