C++ nested static structs/classes?

Started by
13 comments, last by Melekor 19 years, 2 months ago
I was playing around with static classes to do some initialization before the program starts when I found out that this won't link:

static struct Outer
{
	static struct Inner
	{
		int m_inner;

		Inner()
		{
			m_inner = 0xc0de;
		}

	} InnerInstance;

	int m_outer;

	Outer()
	{
		m_outer = 0xbeef;
	}

} OuterInstance;

int main()
{
	printf("%d\n%d\n", OuterInstance.m_outer,
		OuterInstance.InnerInstance.m_inner);
}
It gives me this:
main.obj : error LNK2001: unresolved external symbol "public: static struct Outer::Inner Outer::InnerInstance" (?InnerInstance@Outer@@2UInner@1@A)
Can anyone explain what is going on here? It looks correct to me, and it compiles, so what could the problem be? I'm using VC++ 7.1.
Advertisement
have you tried putting "Outer::Inner Outer::InnerInstance;" in a cpp file somewhere?

With static member variables you need to initialize them someplace. I'm pretty sure that applies even with a default constructor.
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Hm... yes... that seems to be the problem. Apparently only integers can be initialized inside the class body. Well that is one of the dumbest things about C++ I've ever heard of. I swear I'm going to write my own language some day. So much for my cool auto window class registration scheme :( The code I'm going to have to use now is way less elegant. Anyways, thanks for the help Erzengeldeslichtes.
Quote:Original post by Melekor
Hm... yes... that seems to be the problem. Apparently only integers can be initialized inside the class body.
Nope, you can't even do it with basic types. It all has to go into a source file.
Yulp, in-class initialization is allowed only for builtin types, ie, int, char, float, etc.

Whoops.. I remembered slightly wrong... anyways, a quote from Effective C++:

"Older compilers may not accept this syntax, because it used to be illegal....
in-class initialization is allowed only for integral types (ints, bools, chars, etc)."
It's not an initialization problem, it's a definition problem. The static Inner InnerInstance; in the class definition is just a declaration (like extern int foo; would be).
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
It is not an issue of initialization, it is an issue of instantiation. In the following struct, the static member "bar" must be instantiated somewhere since it is only declared in FOO.
struct FOO{    static int bar; //<-- this is a declaration only    int baz;        //<-- this is an instantiation}; 

Somewhere you have to instantiate FOO::bar.
int FOO::bar = 0xC0FFEE; // for example
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by Melekor
Well that is one of the dumbest things about C++ I've ever heard of. I swear I'm going to write my own language some day.

C++ isn't perfect, it's practical. Personally, I don't mind the static member initialization. Note that using automatic initializations by using global variables can get a bit hairy if one requires another, it's not defined what order globals are initialized.
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
Since it is supposed to work for builtin types, this should work(right?):

struct Test{	static const int m_static = printf("hi");};int main(){	printf("%d\n", Test::m_static);}


This should output

hi
2

but actually it only outputs

0

So have I just found the 2% of vc++7.1 that isn't standard compliant or am I still doing something wrong?
Only constant static *integral* types can be initialised in the class declaration. Integral types, more integral types, const static integral (at the bottom)

cheers
sam.

This topic is closed to new replies.

Advertisement