Sign in to follow this  

C++ nested static structs/classes?

This topic is 4691 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)."

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Quote:
Original post by izzo
Only constant static *integral* types can be initialised in the class declaration.


Quote:
Original post by Melekor
struct Test
{
static const int m_static = printf("hi");
};


It is a constant static integral and yet it's not working. That's why I'm inclined to think this is a compiler problem, can someone confirm that?

Share this post


Link to post
Share on other sites
Sorry, you posted while I was posting, so otherwise I would have commented above.

I had a look at the assembly output of your test case and it doesn't seem to call printf at all (I tried it in gcc and gcc doesn't even compile). So it looks like it's just ignoring the call to printf.. the value would be 0 because it is instantiated in an initialised data section (bss), I expect..

sam.


[Edited by - izzo on February 7, 2005 10:12:40 PM]

Share this post


Link to post
Share on other sites
It is a compiler problem, as that code shouldn't compile!
main.cpp:8: error: `int printf(const char*, ...)' cannot appear in a constant-expression
main.cpp:8: error: a function call cannot appear in a constant-expression

(edit) beaten to the punch!

Share this post


Link to post
Share on other sites
Yeah, I'm using VC++ .NET 2003 Standard edition so I guess it's borked :( It seems to just ignore the call which is pretty strange..

sam.

[Edited by - izzo on February 7, 2005 10:14:19 PM]

Share this post


Link to post
Share on other sites

This topic is 4691 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this