Sign in to follow this  
nuclear123

static variables?

Recommended Posts

When people ask "what's do difficult about C++, pointers aren't that hard?", it's this kind of crap you should point at. I simply don't know why the C++ spec wouldn't state "statics are guaranteed to be implemented before ____", but these various vagarities contribute to why C++ is hard to learn... or frankly, deal with on a daily basis.

Share this post


Link to post
Share on other sites
Serapth, what difference does it make in this case? There is no way to notice the difference so you don't have to know. Better give the compiler the freedom to decide what is most suitable.

Share this post


Link to post
Share on other sites
[quote name='Wooh' timestamp='1317777948' post='4869177']
Serapth, what difference does it make in this case? There is no way to notice the difference so you don't have to know. Better give the compiler the freedom to decide what is most suitable.
[/quote]

Because the OP's question is completely legit and should have a better answer than "it depends on what the compiler maker implements". [ no fault against SiCrane's answer, which was completely correct ]

I applaud the OP for asking what amounts to a very good question, and I decry C++ for not having a good answer. I can't honestly think of another (modern) language where the answer would have been "implementation defined" on such a core detail. These ambiguities are what make C++ such a bitch of a ?beginners? language, and within this forum, it feels appropriate to point out such an apt example when it presents itself.


Now, if you are implying that order of instantiation has no importance beyond a compiler issue, you obviously haven't been bit in the ass by this particular issue. It happens and it hurts. Lots.

Share this post


Link to post
Share on other sites
[quote name='nuclear123' timestamp='1317775522' post='4869164']
when is this variable initialized to 3?
[/quote]

[i][b]Before the first time it's accessed. [/b][/i]


Part of the problem here might be that static init objects are inherited from C. C had no classes, hence no constructors, and hence no arbitrary code execution when initializing static objects. It was enough for them to be initialized before they were used. And "before main()" was more than enough to guarantee that.

With the advent of C++, it was decided not to impose further restrictions on the compiler. Probable reasons for this are:[list]
[*]The makers of C compilers would more quickly produce C++ compilers the fewer complications that were piled on.
[/list][list]
[*]Given the flexibility, compilers could conceivably re-strategize initialization to optimize (code size and/or processing time) as desired.
[/list][list]
[*]The language specifiers decided that it was ok to implicitly require code to [i][b]not [/b][/i]depend on static init order.
[/list]
The problem we're left with is that the requirement to not depend on static init order is generally something programmers have to learn the hard way. It's too easy to run afoul of this restriction and compilers can't detect when you have, or warn you when you do.

But on the other hand, it may be that there is no definitive order which really makes life better. In other words, if there was an authoritative order:[list]
[*]It might be non-trivial to work out (i.e. it might not be an explicit order, but rather an algorithm to determine an order).
[/list][list]
[*]It might create other cascading restrictions.
[/list][list]
[*]Rather than learning the hard way that there's no defined order, programmers would just be learning the hard way how that order worked. After having created and diagnosed a problem, they would still have to redesign their solutions to work with it, which would likely be about (if not exactly) the same as redesigning to not depend on it.
[/list][list]
[*]And again, the compiler wouldn't be able to detect or warn you when your implementation wasn't going to work with the initialization order.
[/list]
But at the end of the day, the language does provide certain guarantees (e.g. static local variables are initialized before they're first accessed.) which allow programmers to interact with static init data in a deterministic way. Edited by VReality

Share this post


Link to post
Share on other sites
[quote name='Serapth' timestamp='1317778584' post='4869179']
I can't honestly think of another (modern) language where the answer would have been "implementation defined" on such a core detail.
[/quote]

Out of curiosity, how is static initialization order handled in your favorite language(s)?

Share this post


Link to post
Share on other sites
[quote name='SiCrane' timestamp='1317776616' post='4869171']
This is implementation defined. It could be initialized before main runs or it could be initialized the first time the function is called.
[/quote]
An important point of this is that by having it in a function, you guarantee that it will be initialized when the function is called EVEN if it is called before main via another static initialization. Without having it in the function you lose that guarantee, and you can end up with the static initialization order fiasco.

[url="http://stackoverflow.com/questions/55510/when-do-function-level-static-variables-get-allocated-initialized/58804#58804"]Someone else[/url] took the time to find the relevent sections of the standard, so I'll requote from them.

[quote= name='C++ Standardese']4 The zero-initialization (dcl.init) of all local objects with static storage duration (basic.stc.static) is performed before any other initialization takes place. A local object of POD type (basic.types) with static storage duration initialized with con- stant-expressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (basic.start.init). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If con- trol re-enters the declaration (recursively) while the object is being initialized, the behavior is undefined. [Example: int foo(int i) { static int s = foo(2*i); // recursive call - undefined return i+1; } --end example][/quote] Edited by Slavik81

Share this post


Link to post
Share on other sites
[quote name='nuclear123' timestamp='1317775522' post='4869164']
When[/quote]

Early enough for you to use it in the normal ways (i.e. to expect that it is initialized, and has the value 3, before the first time it is referred to within the code of the function).

This is deliberately vague, so that the compiler can do it in the way that makes your program run as fast as possible. If you really need to know more precisely in order for your code to work, you are taking the wrong approach in your code. If you care just for the sake of caring, that's admirable in a way, but ultimately unproductive.

Share this post


Link to post
Share on other sites

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