Global object initialization

K

kiryazev

Hello. Given the code below does C++ Standard guarantee that the
function my_init() will be called before main()?

struct A
{
A()
{
my_init();
}
};

A g_a;

int main()
{
// ...
}
 
A

asm23

Hello. Given the code below does C++ Standard guarantee that the
function my_init() will be called before main()?

struct A
{
A()
{
my_init();
}
};

A g_a;

int main()
{
// ...
}
Yes, a global variable will be initialized *before* main() entered. So,
the constructor of A will call my_init() before main().
 
Z

Zeppe

Pete said:
In this example, that's true. But there's nothing special about main.

There is, indeed. And in particular, since main cannot be called
explicitly, you are sure that the static variable is initialised
before.In addition, I'd say all the static variables from all the
translation units are initialised before main() is called. What is
undefined is the order of initialisation of static variables from
different translation units. So, if g_a is used in a function foo that
is called during the initialisation of a global variable in another
translation unit, there can be problems.

Usually in this cases a function returining a reference to the static
variable can force a safe order of initialisation (even though by itself
doesn't guarantee the initialisation before main).

A g_a()
{
static A g_a;
return g_a;
}

Best wishes,

Zeppe
 
Z

Zeppe

Pete said:
In this example, that's true. But there's nothing special about main.

There is, indeed. And in particular, since main cannot be called
explicitly, you are sure that the static variable is initialised
before.In addition, I'd say all the static variables from all the
translation units are initialised before main() is called. What is
undefined is the order of initialisation of static variables from
different translation units. So, if g_a is used in a function foo that
is called during the initialisation of a global variable in another
translation unit, there can be problems.

Usually in this cases a function returining a reference to the static
variable can force a safe order of initialisation (even though by itself
doesn't guarantee the initialisation before main).

A g_a()
{
static A g_a;
return g_a;
}

Best wishes,

Zeppe
 
M

Maxim Yegorushkin

In this example, that's true. But there's nothing special about main.
Global variables will be initialized before entry into any function
defined in the same translation unit as the variable.

Please note, that there is nothing preventing a function to be called
before the global variables from the same translation unit are
initialised. For example, from a constructor of a global object from
another TU which happens to be initialised before the TU where the
function resides.
 
J

James Kanze

In this example, that's true. But there's nothing special
about main. Global variables will be initialized before entry
into any function defined in the same translation unit as the
variable. So if this function was named foo instead of main
and main was defined in another translation unit, there would
be no inherent connection between entry into main and
initialization of g_a. Rather, the requirement would be that
g_a be initialized before entry into foo.

According to the standard. In practice, however, all compilers
do initialize all global variables before entering main. It's a
lot simpler than trying the handle the cyclic dependencies which
can occur otherwise. And there's enough code out there which
depends on it that no compiler today would dare break it.
 
J

James Kanze

On 2008-09-30 09:02:29 -0400, Zeppe
<[email protected]> said:
Well, yes, main is in some ways special. But we were talking
about initialization, and the rule, once again, is that static
objects must be initialized before the first entry into any
function defined in the same translation unit. It doesn't
matter whether the name of that function is main, foo, bar, or
billy. And it doesn't matter whether main is also in that
translation unit.

What the current standard says is that "if the initialization is
deferred to some point in time after the first statement of
main, it shall occur before the first use of any function or
object defined in the same translation unit as the object to be
initialized."

The standard doesn't really define what it means by use, which
makes it rather hard to figure out what is really meant. (Is
taking the address of an object "use"? What if the address is
used to initialize a static pointer?) On the whole, it opens
the door to possible cycles, in which the compiler is required
to initialized A before B, and B before A.

The issue is further muddled by the statement in the current
draft that "Non-local objects with static storage duration are
initialized as a consequence of program initiation." Again,
it's not really too clear what this means, but "program
initiation" certainly suggests "before the first statement in
main".

And of course, no compiler actually does defer the
initialization until after main. In practice, several
widespread idioms count on it, and no compiler would dare to
break them. So in practice, it's safe to say that
initialization does occur before the first statement in main,
even if the standard explicitly gives an implementation other
alternatives.

[...]
That's not required by the standard. The rule is as I've set out above.
That's a provision for dynamically linked libraries, which can be
loaded on demand, and don't initialize their statics until they are
loaded.

And which also violate the phases of translation, and so are
"undefined behavior" as far as the standard is concerned.
(Obviously, implementations do define this behavior. Just as
obviously, if you're using dynamic linking, you turn to the
guarantees given by your implementation.)
 

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

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top