When does static initialization occur?

J

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().

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

John
 
A

Andre Kostur

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.
 
S

Salt_Peter

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.
 
J

JohnQ

Salt_Peter said:
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
 
J

JohnQ

Andre Kostur said:
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
 
A

Alf P. Steinbach

* 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++.
 
P

Pete Becker

JohnQ said:
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)
 
A

Alf P. Steinbach

* Pete Becker:
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"?
 
P

peter koch

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
 
P

Pete Becker

peter said:
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)
 
J

JohnQ

Pete Becker said:
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
 
J

JohnQ

Alf P. Steinbach said:
* JohnQ:

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".
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.


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
 
I

Ian Collins

JohnQ said:
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.
 
A

Alf P. Steinbach

* JohnQ:
Alf P. Steinbach said:
[snip]
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.

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.
 
P

pawel.kunio

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
 
P

Pete Becker

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)
 
J

James Kanze

On May 26, 12:42 am, "JohnQ" <[email protected]>
wrote:
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.
 
J

JohnQ

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
 
J

James Kanze

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,592
Members
45,104
Latest member
LesliVqm09
Top