C++11 allows static member initialisation

  • Thread starter Single Stage to Orbit
  • Start date
S

Single Stage to Orbit

I have this:

$ more static-initialisers.cpp
class Simple
{
static int mCounter = 0;
};
$ g++-4.6.3 -std=c++0x -c static-initialisers.cpp
static-initialisers.cpp:3:24: error: ISO C++ forbids in-class
initialization of non-const static member ‘mCounter’

Which version of G++ allows this? The docs for 4.7.x doesn't say if it
is allowed.

I know I can simply do:

int Simple::mCounter = 0

to get around this though.
 
L

Luca Risolia

I have this:

$ more static-initialisers.cpp
class Simple
{
static int mCounter = 0;
};
$ g++-4.6.3 -std=c++0x -c static-initialisers.cpp
static-initialisers.cpp:3:24: error: ISO C++ forbids in-class
initialization of non-const static member ‘mCounter’

Which version of G++ allows this?

None probably.
The docs for 4.7.x doesn't say if it is allowed.

With --std=C++0x, GCC obeys to the C++11 standard (§ 9.4.2):

"
The definition for a static data member shall appear in a namespace
scope enclosing the member’s class definition. In the definition at
namespace scope, the name of the static data member shall be qualified
by its class name using the :: operator. The initializer expression in
the definition of a static data member is in the scope of its class
(3.3.7).

[ Example:

class process {
static process* run_chain;
static process* running;
};
process* process::running = get_main();
process* process::run_chain = running;
"
 
J

Juha Nieminen

Single Stage to Orbit said:
class Simple
{
static int mCounter = 0;
};
$ g++-4.6.3 -std=c++0x -c static-initialisers.cpp
static-initialisers.cpp:3:24: error: ISO C++ forbids in-class
initialization of non-const static member ???mCounter???

Which version of G++ allows this? The docs for 4.7.x doesn't say if it
is allowed.

Why do you assume that it's allowed?

I think you are confusing it with (non-static) in-class member
initialization. That's a different thing. (It's basically a shortcut
to writing the initialization into the constructor of the class. Static
variables are not initialized in the constructor.)
 
S

Single Stage to Orbit

Why do you assume that it's allowed?

Because "Professional C++ 2nd Edition" says that with C++11 I can do
this. Evidently it is wrong.
I think you are confusing it with (non-static) in-class member
initialization. That's a different thing. (It's basically a shortcut
to writing the initialization into the constructor of the class.
Static variables are not initialized in the constructor.)

Or has the standard changed to disallow static in-class member
initialization?
 
J

Juha Nieminen

Paavo Helde said:
Only const static data members can be initialized in-class. For a mutable
data member the identity of the variable is important, so it must be placed
in a specific compilation unit.

Btw, at some point in the distant past, gcc (a really old version of it,
obviously) demanded that even const static class variables be defined in
a compilation unit. (Ostensibly so you can create pointers pointing to
that variable.)

What exactly is the current official status of this? Does the standard
explicitly say that const static class variables do not need to be
defined in a compilation unit? Why was gcc demanding it at one point?
(Was this a concept before the 98 standard came out? Was it in some
standard draft? Was it in the standard but got changed? Was this simply
something gcc-exclusive?)

What happens if you take the address of a const static class variable?
(Error? Malformed? Implementation-defined? UB? Must have definition in
this case? Something else?)
 
J

Juha Nieminen

Paavo Helde said:
The compiler cannot guess in which compilation unit it should appear.

It doesn't seem to be a problem with static variables in a templated
class...
 
J

Juha Nieminen

Single Stage to Orbit said:
Or has the standard changed to disallow static in-class member
initialization?

Does the new standard really say that you can now initialize static
members in their declaration?

Note that non-static member initialization in their declaration is
not *actual* initialization per se. It's just a shorthand that can be used
instead of writing the actual initialization in the constructor of the class.
(Note that when you write "int i = 5;" as class member, that variable
might not actually be initialized with the value 5. A constructor my
override that initialization with something else in its initializer
list. The initialization to 5 will be autogenerated only if there's
no explicit initialization in the initialization list of the constructor.)

Static members are not initialized in constructors, and hence it's
a completely different situation.
 
A

Alf P. Steinbach

Btw, at some point in the distant past, gcc (a really old version of it,
obviously) demanded that even const static class variables be defined in
a compilation unit. (Ostensibly so you can create pointers pointing to
that variable.)

What exactly is the current official status of this? Does the standard
explicitly say that const static class variables do not need to be
defined in a compilation unit? Why was gcc demanding it at one point?
(Was this a concept before the 98 standard came out? Was it in some
standard draft? Was it in the standard but got changed? Was this simply
something gcc-exclusive?)

It's still a bit fuzzy, but the intent appears to be that if the address
is never required, then it's A OK to not have definition.

As I recall it's still specified in the One Definition Rule.

What happens if you take the address of a const static class variable?

Then you need a definition.

If you want such a definition in a header, it can be placed in base
class template.


Cheers & hth.,

- Alf
 
V

Victor Bazarov

Does the new standard really say that you can now initialize static
members in their declaration?

Just to remind the OP, const static members are allowed to be
initialised in the class definition, and that hasn't changed in the new
Standard; *some* compilers *extend* this behavior to include non-const
static data members, but let's emphasize that it is *an extension*.

V
 
J

Juha Nieminen

Paavo Helde said:
Experimentation shows otherwise:

template<typename T>
struct A {
static int bb;
void f() {bb=42;}
};


int main() {
A<int> x;
x.f();
}

I didn't say that you don't need to define the static variable. I meant
to say that you can define it right there in the header, and it doesn't
seem to cause any problem for the compiler to decide "in which compilation
unit it should appear"

My point was that the argument that the compiler needs to know the exact
compilation unit where to put the static variable is not valid because
templated classes demonstrate otherwise.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top