[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Global object initialization

kiryazev

9/30/2008 7:36:00 AM

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()
{
// ...
}
9 Answers

asm23

9/30/2008 8:08:00 AM

0

kiryazev@gmail.com wrote:
> 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().

Pete Becker

9/30/2008 10:45:00 AM

0

On 2008-09-30 04:07:55 -0400, asm23 <asmwarrior@gmail.com> said:

> kiryazev@gmail.com wrote:
>> 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().

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.

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

Zeppe

9/30/2008 1:02:00 PM

0

Pete Becker wrote:

> 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

Zeppe

9/30/2008 1:03:00 PM

0

Pete Becker wrote:

> 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

Pete Becker

9/30/2008 2:27:00 PM

0

On 2008-09-30 09:02:29 -0400, Zeppe
<zep_p@remove.all.this.long.comment.yahoo.it> said:

> Pete Becker wrote:
>
>> In this example, that's true. But there's nothing special about main.
>
> There is, indeed.

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.

> And in particular, since main cannot be called explicitly, you are
> sure that the static variable is initialised before.

Again: that's true for every function, regardless of whether it can be
called explicitly.

> In addition, I'd say all the static variables from all the translation
> units are initialised before main() is called.

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.

> What is undefined is the order of initialisation of static variables
> from different translation units.

That is unspecified, not undefined. But it's subject to the rule about
initizaliation before use of a function, as above.

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

Indeed.

>
> 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;
> }
>

That's one way to manage initialization order, but that's a separate
issue from the requirement about initialization before entry into a
function.

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

Maxim Yegorushkin

9/30/2008 3:37:00 PM

0

On Sep 30, 11:44 am, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-09-30 04:07:55 -0400, asm23 <asmwarr...@gmail.com> said:
>
>
>
> > kirya...@gmail.com wrote:
> >> 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().
>
> 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.

--
Max

Pete Becker

9/30/2008 3:53:00 PM

0

On 2008-09-30 11:37:05 -0400, Maxim Yegorushkin
<maxim.yegorushkin@gmail.com> said:

>
> Please note, that there is nothing preventing a function to be called
> before the global variables from the same translation unit are
> initialised.

Now that I've looked it up, I see that I've overstated the rule. The
actual rule is that It's implementation-defined whether the
implementation does dynamic initialization before entry into main. If
it defers initialization, it must do dynamic initialization of objects
defined in a translation unit before the first use of any function or
object defined in the same translation unit. So in the typical case
where all the translation units are linked together and their statics
are initialized before entry into main, there is no requirement on the
relative order of dynamic initialization of objects defined in
different translation units.

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

James Kanze

10/1/2008 8:24:00 AM

0

On Sep 30, 12:44 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-09-30 04:07:55 -0400, asm23 <asmwarr...@gmail.com> said:
> > kirya...@gmail.com wrote:
> >> 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().

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

--
James Kanze (GABI Software) email:james.kanze@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

James Kanze

10/1/2008 8:42:00 AM

0

On Sep 30, 4:27 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-09-30 09:02:29 -0400, Zeppe
> <ze...@remove.all.this.long.comment.yahoo.it> said:

> > Pete Becker wrote:

> >> In this example, that's true. But there's nothing special
> >> about main.

> > There is, indeed.

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

[...]
> > In addition, I'd say all the static variables from all the translation
> > units are initialised before main() is called.

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

--
James Kanze (GABI Software) email:james.kanze@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