Hi,
By the standard C++ will a ever be initialized when there are no calls to foo?Code:void foo()
{
static int a = 0;
}
int main()
{
return 0;
}
many thanks
Printable View
Hi,
By the standard C++ will a ever be initialized when there are no calls to foo?Code:void foo()
{
static int a = 0;
}
int main()
{
return 0;
}
many thanks
I dont think so. Function statics are initialised on first use I believe.
You could check yourself here.
Nothing has changed since Kernigan&Ritchie's statement was published: static variable (inside a function) is initialized at the time of the first call to the function.
Anyway, what are going to clarify this issue for, just for the sake of interest? :)
Internally, this variable will be a global variable and will be initialized to 0 at the time the program is loaded. Declaring it static simply limits its scope within the function.
Here's a critical review,
http://www.tilander.org/aurora/2007/...tion-in-c.html
This conflicts with what others have been saying. Who is correct?
You could try something like this to prove the point:
Code:class foo
{
foo() { std::cout << "fooclass constructed!" << std::endl; }
};
foo& getFooInstance()
{
static foo theObject;
return theObject;
}
in the main function create some dummy code before the call to foo() and set a breakpoint before the call. See if the class was constructed before the first call.
Object creation is a 2 step process.
The actual object creation and a constructor call.
kempofighter's example doesn't disprove my point of view.
What I would say here is that the object construction still happens when the program is loaded.
It is only the constructor call that is deferred till the function is actually called.
I have a program here to prove my point.
The sample program is like so.
void fun()
{
static int i = 100;
}
int main()
{
fun();
return 0;
}
In visual studio, I have generated the assembly code from my code using the /FA compiler flag.
I'm posting relevant parts of the asm code here.
_DATA SEGMENT
?i@?1??fun@@YAXXZ@4HA DD 064H ; `fun'::`2'::i
_DATA ENDS
_TEXT SEGMENT
?fun@@YAXXZ PROC ; fun, COMDAT
; 8 : static int i = 100;
; 9 : }
ret 0
_TEXT ENDS
_TEXT SEGMENT
_main PROC
; 13 : fun();
; 14 : return 0;
xor eax, eax
; 15 : }
ret 0
_main ENDP
_TEXT ENDS
END
Inside the fun PROC there is only a ret 0 and no initialization code.
In the global data segment a label has been defined and initialized with the value 064H which is 100.
Well that is a good point. It seems like the compiler is optimizing here to avoid double initializing the memory. I wonder if it will always do that or only because you have some optimization enabled. Also, as far as the standard is concerned, I'm not sure if this is required by the c++ standard. Then again, this function is really pointless since it doesn't do anything so of course there is just a return 0 in the assembly.
However, I don't believe the compiler will do this for non-POD objects. The static singleton method isn't threadsafe because although the compiler may set aside memory for a static object, an object's constructor will still be called when the function executes and multiple threads calling a static function could cause two objects to be constructed. I think that is a more important point to remember about static instances of variables/objects within a function.
The original question is pretty simple but I'm always worried that simple answers will lead one astray. Don't make assumptions about more complex scenarios based on this one sample. It is nice to know that the compiler is setting aside some memory for the static and in the case of PODs is initializing the memory efficiently. statics work in this context because there is memory being set aside that will hold its value across function calls and because the item will only be constructed once. The fact that a POD with simple initialization could "technically" be initialized prior to the function call isn't as important as understanding the behavior when complex constructors are involved. That's just my 2 cents.
If you use an assembler and don't use a compiler at all, then this would be the only way to do it. So its really not an optimization.
Coming to objects, constructor calls finally boil down to a function call.
If you look at the assembly output for local static objects, you will see that memory is allocated when the program loads and the constructor call is made when the function is first called.
But then, objects are totally different in this context. I mean, the initial question was what I was trying to target.
The C++ standard agrees with _Superman_:Quote:
Originally Posted by kempofighter
Quote:
Originally Posted by C++03 Section 3.7.1 Paragraph 1
On the other hand, Russco and AmadeusAD are not wrong either:Quote:
Originally Posted by C++03 Section 6.7 Paragraph 4
Quote:
Originally Posted by C++03 Section 3.7.1 Paragraph 2
So, since the initialisation of a in foo() has no side effects as in Salvadoravi's example, it can be (but it does not have to be) eliminated if it appears to be unused.Quote:
Originally Posted by C++03 Section 6.7 Paragraph 4
There is a different behavior for the languages C and C++ and this tends to be quite confusing.
In C++ function-local non-constant statics as well as function-local constant statics are initialized once and only once. And this occurs at the time of first run-time execution of the initialization line.
In C both function-local non-constant statics as well as function-local constant statics are initialized by the compiler before the call to main. This is usually carried out in the startup assembly routines which initialize the C run-time environment such as stack, run-time library, etc.
If you consider these differences you will note that C++ can initialize statics with complicated program elements such as function calls. However in C only simple constant POD values can be used as initializers of statics.
Sincerely, Chris.
Laserlight, thanks for finding the relevant entries in the std.
After thinking about it some more, superman is absolutely correct in answering the very specific question of the OP, since the OP chose to initialize the variable with a constant. It is a tricky question because the answer might change depending on how the programmer writes the function. Although the specific answer is simpler than I thought, hopefully the OP is now aware of what happens when adding a function call to the initialization of that variable.
Guys thanks very much for the info.
Lazerlight thank you for the std !!