By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,136 Members | 1,089 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,136 IT Pros & Developers. It's quick & easy.

When does static initialization occur?

P: n/a
The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B? What
happens during A?

John
May 25 '07 #1
Share this Question
Share on Google+
20 Replies


P: n/a
"JohnQ" <jo***********************@yahoo.comwrote in
news:FC****************@newssvr19.news.prodigy.net :
The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or
B? What happens during A?

John
I thought main was the entry point. Anything else would be platform-
specific. So from the Standard point of view, I thought:

1) The stuff that happens before main
2) The stuff that happens in main

Global objects are initialized in 1.
May 25 '07 #2

P: n/a
On May 25, 6:42 pm, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B? What
happens during A?

John
main() is the entry point.
The answer depends on whether the static variable is local or not (in
which case Construct on First Use applies). Is the static variable a
member of a class? Was it defined? Is it a global (in a compilation
unit)?

You might gain some insight with the FAQ:
[10.11] Why are classes with static data members getting linker
errors?
[10.12] What's the "static initialization order fiasco"?
[10.13] How do I prevent the "static initialization order fiasco"?
[10.15] How do I prevent the "static initialization order fiasco" for
my static data members?

http://www.parashift.com/c++-faq-lite/ctors.html

If you still need clarification, post a simple example.

May 26 '07 #3

P: n/a

"Salt_Peter" <pj*****@yahoo.comwrote in message
news:11**********************@g4g2000hsf.googlegro ups.com...
On May 25, 6:42 pm, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B?
What
happens during A?

John

main() is the entry point.
The answer depends on whether the static variable is local or not (in
which case Construct on First Use applies). Is the static variable a
member of a class? Was it defined? Is it a global (in a compilation
unit)?
I was asking in general, not for a specific piece of code. I'm calling the
entry point that which my compiler calls the entry point. It is key because
it it the first place in time where I can get control of the program. But if
I do commandiere that point, I need to be prepared to take over the duties
of that phase of startup.

John
May 26 '07 #4

P: n/a

"Andre Kostur" <nn******@kostur.netwrote in message
news:Xn*******************************@209.135.99. 21...
"JohnQ" <jo***********************@yahoo.comwrote in
news:FC****************@newssvr19.news.prodigy.net :
>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or
B? What happens during A?

John

I thought main was the entry point. Anything else would be platform-
specific. So from the Standard point of view, I thought:

1) The stuff that happens before main
2) The stuff that happens in main

Global objects are initialized in 1.
I wonder what the standard says about that (for implementors). Does it
really just recognize 2 phases or are there more? It seems to me that
initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.

A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().

John
May 26 '07 #5

P: n/a
* JohnQ:
The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().
First, about terminology. "Entry point" in general means the address
where execution of the program's own machine code starts. "Entry point"
in the context of a particular language often means the language's
designated startup function (if there is one), such as C++ "main", which
is not the machine code level entry point.

You're using the general, not language-specific, meaning.

So, if the above is OK, does static initialization occur during A or B?
Generally in B. The standard allows delayed initialization in C, but
then before the first call of a function in the translation unit. The
wording of this is not perfect and it's probably the only place in the
standard where there is any kind of support for dynamic libraries (not
all agree that it is in support of dynamic libraries).

What happens during A?
That's system specific and generally only of interest if you're going to
write a runtime library replacement using risky techniques instead of
the better documented ways. Anyway, it has nothing to do with C++.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 26 '07 #6

P: n/a
JohnQ wrote:
>
I wonder what the standard says about that (for implementors). Does it
really just recognize 2 phases or are there more? It seems to me that
initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.

A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().
Nope. There are two phases of initialization: static and dynamic.
Zero-initialization and constant initialization are static
initializations. Anything else is dynamic. Static initialization occurs
before entry into main and before dynamic initialization. Dynamic
initialization is allowed to be postponed until the first use of any
function or object defined in the same translation unit.

When you get down into the mechanics, static initialization means
stuffing values known at compile time into memory locations. That
information can be stored directly in the executable file, and the
loader can handle it. Dynamic execution requires some sort of
computation at runtime. The program's startup code does it. (The
compiler is allowed to convert dynamic initializations into static ones
if that doesn't change the value or any values that depend on that value)

The standard library can, and often does, have implementation-specific
hooks to ensure that critical parts are initialized before their use in
dynamic initialization, but that's not part of the standard (except for
the nifty counter trick for iostreams), nor should it be.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 26 '07 #7

P: n/a
* Pete Becker:
JohnQ wrote:
>>
I wonder what the standard says about that (for implementors). Does it
really just recognize 2 phases or are there more? It seems to me that
initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.

A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().

Nope. There are two phases of initialization: static and dynamic.
Zero-initialization and constant initialization are static
initializations. Anything else is dynamic. Static initialization occurs
before entry into main and before dynamic initialization.
"Before dynamic initialization" yes, but where do you find the
requirement of "before entry into main"?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 26 '07 #8

P: n/a
Alf P. Steinbach wrote:
* Pete Becker:
>JohnQ wrote:
>>>
I wonder what the standard says about that (for implementors). Does
it really just recognize 2 phases or are there more? It seems to me
that initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.

A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().

Nope. There are two phases of initialization: static and dynamic.
Zero-initialization and constant initialization are static
initializations. Anything else is dynamic. Static initialization
occurs before entry into main and before dynamic initialization.

"Before dynamic initialization" yes, but where do you find the
requirement of "before entry into main"?
You're right, not required.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 26 '07 #9

P: n/a
On 26 Maj, 16:37, Pete Becker <p...@versatilecoding.comwrote:
Alf P. Steinbach wrote:
* Pete Becker:
JohnQ wrote:
>I wonder what the standard says about that (for implementors). Does
it really just recognize 2 phases or are there more? It seems to me
that initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.
>A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().
Nope. There are two phases of initialization: static and dynamic.
Zero-initialization and constant initialization are static
initializations. Anything else is dynamic. Static initialization
occurs before entry into main and before dynamic initialization.
"Before dynamic initialization" yes, but where do you find the
requirement of "before entry into main"?

You're right, not required.
Exactly. This allows the implementation to have a "hidden statement"
to be the first thing to be executed in main, where this staetement
performs all global initialisations. This is the reason (so far as I
understood it) that main is not reentrant (an application is not
allowed to call main).

/Peter

May 26 '07 #10

P: n/a
peter koch wrote:
>
Exactly. This allows the implementation to have a "hidden statement"
to be the first thing to be executed in main, where this staetement
performs all global initialisations. This is the reason (so far as I
understood it) that main is not reentrant (an application is not
allowed to call main).
That's certainly the case for dynamic initialization, in large part
because that's how cfront did it. There's less need for this to apply to
static initialziations, which C has always handled. But there's no good
reason to ban it, either.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 26 '07 #11

P: n/a

"Pete Becker" <pe**@versatilecoding.comwrote in message
news:Bs******************************@giganews.com ...
JohnQ wrote:
>>
I wonder what the standard says about that (for implementors). Does it
really just recognize 2 phases or are there more? It seems to me that
initialization of the standard libraries needs to happen before
initialization of globals because the globals may need the library
facilities.

A.) Phase A stuff (as delineated from subsequent phases via the
vendor-supplied entry point override).
B1.) Std library initialization.
B2.) Global object initialization.
B3.) Other stuff in phase B.
C.) main().

Nope. There are two phases of initialization: static and dynamic.
Zero-initialization and constant initialization are static
initializations. Anything else is dynamic. Static initialization occurs
before entry into main and before dynamic initialization. Dynamic
initialization is allowed to be postponed until the first use of any
function or object defined in the same translation unit.

When you get down into the mechanics, static initialization means stuffing
values known at compile time into memory locations. That information can
be stored directly in the executable file, and the loader can handle it.
Dynamic execution requires some sort of computation at runtime. The
program's startup code does it. (The compiler is allowed to convert
dynamic initializations into static ones if that doesn't change the value
or any values that depend on that value)

The standard library can, and often does, have implementation-specific
hooks to ensure that critical parts are initialized before their use in
dynamic initialization, but that's not part of the standard (except for
the nifty counter trick for iostreams), nor should it be.
OK, good explanation. I guess having the "entry point" given by VC++ is a
luxury value-add (one I like by the way).

John
May 27 '07 #12

P: n/a

"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...
>* JohnQ:
>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

First, about terminology. "Entry point" in general means the address
where execution of the program's own machine code starts. "Entry point"
in the context of a particular language often means the language's
designated startup function (if there is one), such as C++ "main", which
is not the machine code level entry point.

You're using the general, not language-specific, meaning.
OK. It would seem to me though that initialization of objects I create are
of the program. Hence, the "entry point" at somewhere just before that
intialization takes place seems more appropriately called "entry point" than
main. "main" seems like "program beginning execution point".
>So, if the above is OK, does static initialization occur during A or B?

Generally in B. The standard allows delayed initialization in C, but then
before the first call of a function in the translation unit. The wording
of this is not perfect and it's probably the only place in the standard
where there is any kind of support for dynamic libraries (not all agree
that it is in support of dynamic libraries).
OK.
>What happens during A?

That's system specific and generally only of interest if you're going to
write a runtime library replacement using risky techniques instead of the
better documented ways.
Can you explain "risky techniques vs. better documented ways"?
>Anyway, it has nothing to do with C++.
Writing a replacement runtime library has nothing to do with C++??

John
May 27 '07 #13

P: n/a
JohnQ wrote:
>
Writing a replacement runtime library has nothing to do with C++??
Not in the context of this Usenet group, it's more of a specific
compiler implementation issue rather than a language one.

--
Ian Collins.
May 27 '07 #14

P: n/a
* JohnQ:
"Alf P. Steinbach" <al***@start.nowrote in message
news:5b*************@mid.individual.net...
>* JohnQ:
>>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().
[snip]
>>What happens during A?
That's system specific and generally only of interest if you're going to
write a runtime library replacement using risky techniques instead of the
better documented ways.

Can you explain "risky techniques vs. better documented ways"?
As an example, in Windows you can (or could), undocumented, just return
from the machine code entry point, as if it were a function called by
the OS. The documented way is to call ExitProcess.

>Anyway, it has nothing to do with C++.

Writing a replacement runtime library has nothing to do with C++??
No, not with the C++ language as defined by the Holy Standard, which is
what we discuss here. Of course it has a lot to do with in-practice
C++. But, it's generally very environment-specific, and so, off-topic.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
May 27 '07 #15

P: n/a
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B? What
happens during A?

John
During A nothing happens, theres no A.

Imagine main or WinMain on windows being the normal function called by
RealEntryPoint - first function called on executing your program,
in effect it calls your main or WinMain function.
Between call to RealEntryPoint and main function, class static, file
static, function static, global variables are constructed.
By standard in random order, but in effect being order of the object
files are linked into the main executable.

Should anything stay unclear on this one, I can provide the example or
explain in more detail.

regards,
paul

May 27 '07 #16

P: n/a
pa*********@gmail.com wrote:
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B? What
happens during A?

John

During A nothing happens, theres no A.
On the contrary: that's often when static initialiaton occurs, before
any code in the executable starts running. The program loader does that.
Imagine main or WinMain on windows being the normal function called by
RealEntryPoint - first function called on executing your program,
in effect it calls your main or WinMain function.
Between call to RealEntryPoint and main function, class static, file
static, function static, global variables are constructed.
By standard in random order, but in effect being order of the object
files are linked into the main executable.
The standard doesn't require random order. It says that the order is
unspecified.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
May 27 '07 #17

P: n/a
On May 27, 11:18 pm, pawel.ku...@gmail.com wrote:
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
The way I understand the startup of a C++ program is:
A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().
So, if the above is OK, does static initialization occur
during A or B? What happens during A?
During A nothing happens, theres no A.
On my systems (Solaris, Linux and Windows), the program is
loaded from disk before starting execution at the entry point.
And static initialization takes place during the load from disk.

Of course, all this isn't very relevant to the C++ programmer.
Static initialization takes place some time before the first
line of code gets executed, or at least before it is possible to
access the variable in any way. So whether the system does it
when loading the program, or arranges for the first access to
trap, and does it then, there's no way to tell in your program.
Imagine main or WinMain on windows being the normal function called by
RealEntryPoint - first function called on executing your program,
in effect it calls your main or WinMain function.
Between call to RealEntryPoint and main function, class static, file
static, function static, global variables are constructed.
Maybe. In practice, this will happen before the first line of
your code in main, but technically, the standard allows a later
initialization.
By standard in random order, but in effect being order of the object
files are linked into the main executable.
An unspecified order. Except that the order is specified within
a single source file; it's only the order of the source files
are treated in which is unspecified. And historically, at least
(i.e. with CFront), the order was in fact the opposite the order
of inclusion by the linker. (As far as I know, this was never
documented nor guaranteed. But it did cover up a certain number
of errors, since statics in low level libraries tended to be
constructed before any statics in the code which used them.) A
quick check shows that g++ still respects this order.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 28 '07 #18

P: n/a

<pa*********@gmail.comwrote in message
news:11**********************@q69g2000hsb.googlegr oups.com...
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
>The way I understand the startup of a C++ program is:

A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().

So, if the above is OK, does static initialization occur during A or B?
What
happens during A?

John

During A nothing happens, theres no A.
From the other posts, they say that program load and static initialization
(probably) occur during A. So, we have:

A.) Program load and (probably) static initialization.
B.) Dynamic initialization, runtime library initialization, registering of
global destructors (?).
C.) main().

John
May 29 '07 #19

P: n/a
On May 29, 5:38 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
<pawel.ku...@gmail.comwrote in message
news:11**********************@q69g2000hsb.googlegr oups.com...
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
The way I understand the startup of a C++ program is:
A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().
So, if the above is OK, does static initialization occur
during A or B? What happens during A?
During A nothing happens, theres no A.
From the other posts, they say that program load and static
initialization (probably) occur during A. So, we have:
A.) Program load and (probably) static initialization.
B.) Dynamic initialization, runtime library initialization, registering of
global destructors (?).
C.) main().
Sort of. The runtime library generally uses the same
initialization mechanisms as the rest, and does nothing special.
(This isn't quite true, and some elements from C, such as stdin,
probably do require special handling.) And there's normally no
need to "register" destructors; exit uses the same means of
finding them that the initialization did.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

May 29 '07 #20

P: n/a

"James Kanze" <ja*********@gmail.comwrote in message
news:11**********************@w5g2000hsg.googlegro ups.com...
On May 29, 5:38 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
<pawel.ku...@gmail.comwrote in message
news:11**********************@q69g2000hsb.googlegr oups.com...
On May 26, 12:42 am, "JohnQ" <johnqREMOVETHISprogram...@yahoo.com>
wrote:
The way I understand the startup of a C++ program is:
A.) The stuff that happens before the entry point.
B.) The stuff that happens between the entry point and the calling of
main().
C.) main().
So, if the above is OK, does static initialization occur
during A or B? What happens during A?
During A nothing happens, theres no A.
From the other posts, they say that program load and static
initialization (probably) occur during A. So, we have:
A.) Program load and (probably) static initialization.
B.) Dynamic initialization, runtime library initialization, registering of
global destructors (?).
C.) main().
"Sort of. The runtime library generally uses the same
initialization mechanisms as the rest, and does nothing special.
(This isn't quite true, and some elements from C, such as stdin,
probably do require special handling.) And there's normally no
need to "register" destructors; exit uses the same means of
finding them that the initialization did."

I probably got the terminology "registering destructors" wrong. I was just
remembering what I "learned" from the LibCTiny documentation. Here'a a quote
from that doc:

"All things considered, getting static constructors to work in LIBCTINY was
relatively easy. It was mostly a matter of defining the right data segments
(specifically, .CRT$XCA and .CRT$XCZ), and calling _initterm from the
correct spot in the startup code. Getting static destructors to work was a
bit trickier.
Unlike the function pointer array that the compiler and linker conspire to
create for static constructors, the list of static destructors to call is
built at runtime. To build this list, the compiler generates calls to the
atexit function, which is part of the Visual C++ runtime. The atexit
function takes a function pointer and adds the pointer to a first-in,
last-out list. When the EXE or DLL unloads, the runtime library iterates
through the list and calls each function pointer."

(LibTinyC is described in an early Dr. Dobbs article and an updated article
(and code) on the web. The article is "Reduce EXE and DLL Size with
LIBCTINY.LIB" by Matt Peitrek).

I'm not sure I'd use it in production code (because I don't have the
required low level knowledge to be confident about it or confidence that I'd
be able to fix it if it "breaks" unexpectedly) but it sure was fun to play
with one day (hehe, actually, I'm still building small test code under that
"environment").

Personally, I don't think it would be out of line to suggest that the "entry
point" be accepted as being under the control of the programmer instead of
just everything after main. That would increase mechanism and decrease
policy in the standard a little. (Now my question is "what is the difference
between a hosted and non-holsted C++ implementation?". Somehow, I think it's
related?).

John
May 30 '07 #21

This discussion thread is closed

Replies have been disabled for this discussion.