C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Confusion about 3.6.2/3

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Matthias Hofmann
Guest





PostPosted: Mon Dec 08, 2003 11:05 pm    Post subject: Confusion about 3.6.2/3 Reply with quote



Hello,

I have just read 3.6.2/3, which says "It is implementation-defined wether or
not dynamic initialization [...] of an object of namespace scope is done
before the first statement of main. 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."

Now I wonder: what if the object to be initialized is used in a function
that is not defined in the same translation unit as the object itself?

Example:

// file1.cpp

#include "a.h";

A a;

// end file1.cpp

// file2.cpp

void f()
{
a.Use();
}

int main()
{
f();
}

// end file2.cpp

As you can see, the global object "a" is used in f(). However, f() is not
defined in the same translation unit as "a". Can anyone point me to the
relevant section of the standard that guarantees that "a" will be
initialized before it is used?

Best regards,

Matthias Hofmann




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Jack Klein
Guest





PostPosted: Tue Dec 09, 2003 10:55 am    Post subject: Re: Confusion about 3.6.2/3 Reply with quote



On 8 Dec 2003 18:05:20 -0500, "Matthias Hofmann"
<hofmann (AT) anvil-soft (DOT) com> wrote in comp.lang.c++.moderated:

Quote:
Hello,

I have just read 3.6.2/3, which says "It is implementation-defined wether or
not dynamic initialization [...] of an object of namespace scope is done
before the first statement of main. 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."

Now I wonder: what if the object to be initialized is used in a function
that is not defined in the same translation unit as the object itself?

Then it is not guaranteed to be defined when used.

Quote:
Example:

// file1.cpp

#include "a.h";

A a;

// end file1.cpp

// file2.cpp

void f()
{
a.Use();
}

int main()
{
f();
}

// end file2.cpp

As you can see, the global object "a" is used in f(). However, f() is not
defined in the same translation unit as "a". Can anyone point me to the
relevant section of the standard that guarantees that "a" will be
initialized before it is used?

There is no such guarantee.


--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Dec 09, 2003 8:09 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote



"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote


Quote:
I have just read 3.6.2/3, which says "It is implementation-defined
wether or not dynamic initialization [...] of an object of namespace
scope is done before the first statement of main. 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."

Now I wonder: what if the object to be initialized is used in a
function that is not defined in the same translation unit as the
object itself?

The guarantee is that the object will be initialized before any function
or object defined in the same translation unit as the object to be
initialized. Where it is used doesn't make any difference; an object is
forceably in the same translation unit as itself, and so will be
initialized before use (provided, of course, that that use is after main
has been entered).

Quote:
Example:

// file1.cpp

#include "a.h";

A a;

// end file1.cpp

// file2.cpp

void f()
{
a.Use();
}

int main()
{
f();
}

// end file2.cpp

As you can see, the global object "a" is used in f(). However, f() is
not defined in the same translation unit as "a". Can anyone point me
to the relevant section of the standard that guarantees that "a" will
be initialized before it is used?

You've just quoted it. You are using the object a. That object is
defined in the translation unit file2. Initialization of all objects in
file2 must take place before the first use of a.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Wed Dec 10, 2003 8:28 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote


<kanze (AT) gabi-soft (DOT) fr> schrieb in im Newsbeitrag:
[email]d6652001.0312090613.7fb5bb1f (AT) posting (DOT) google.com[/email]...
Quote:
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message
news:<br2mp0$4ad$1 (AT) news1 (DOT) nefonline.de>...

I have just read 3.6.2/3, which says "It is implementation-defined
wether or not dynamic initialization [...] of an object of namespace
scope is done before the first statement of main. 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."

Now I wonder: what if the object to be initialized is used in a
function that is not defined in the same translation unit as the
object itself?

The guarantee is that the object will be initialized before any function
or object defined in the same translation unit as the object to be
initialized. Where it is used doesn't make any difference; an object is
forceably in the same translation unit as itself, and so will be
initialized before use (provided, of course, that that use is after main
has been entered).

Having read Jack Klein's post, I was kind of shocked, as it states that a
global object could easily be used before it is initialized, which defeats
the purpose of constructors! Now reading your post, I am glad to hear that
this seems to be wrong, but I still wonder why the standard requires that
the initialization "shall occur before the first use of any function or
object defined in the same translation unit as the object to be
initialized." I mean, it does not matter when the object is initialized as
long as it happens before it is used, so why should it have to be
initialized before any other function or object is used?

Quote:

Example:

// file1.cpp

#include "a.h";

A a;

// end file1.cpp

// file2.cpp

void f()
{
a.Use();
}

int main()
{
f();
}

// end file2.cpp

As you can see, the global object "a" is used in f(). However, f() is
not defined in the same translation unit as "a". Can anyone point me
to the relevant section of the standard that guarantees that "a" will
be initialized before it is used?

You've just quoted it. You are using the object a. That object is
defined in the translation unit file2. Initialization of all objects in
file2 must take place before the first use of a.


The object "a" is define din translation unit file1, and it is the one and
only object defined there. If Jack Klein should be right, there is no
guarantee that it will be initialized before it is used.

Best regards,

Matthias Hofmann



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Thu Dec 11, 2003 9:08 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
kanze (AT) gabi-soft (DOT) fr> schrieb in im Newsbeitrag:
[email]d6652001.0312090613.7fb5bb1f (AT) posting (DOT) google.com[/email]...
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message
news:<br2mp0$4ad$1 (AT) news1 (DOT) nefonline.de>...
I have just read 3.6.2/3, which says "It is implementation-defined
wether or not dynamic initialization [...] of an object of
namespace scope is done before the first statement of main. 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."

Now I wonder: what if the object to be initialized is used in a
function that is not defined in the same translation unit as the
object itself?

The guarantee is that the object will be initialized before any
function or object defined in the same translation unit as the
object to be initialized. Where it is used doesn't make any
difference; an object is forceably in the same translation unit as
itself, and so will be initialized before use (provided, of course,
that that use is after main has been entered).

Having read Jack Klein's post, I was kind of shocked, as it states
that a global object could easily be used before it is initialized,
which defeats the purpose of constructors!

Non-local objects can easily be used before they are initialized. By or
from constructors of other non-local objects. The only guarantees the
standard gives you is that non-local objects used after main has started
will be constructed, and that within a single translation unit,
non-local objects will be constructed in lexical order. If the
constructor of a non-local object uses another non-local object in a
different compilation unit, all bets are off.

And a quick aside concerning vocabulary. The C++ standard uses the word
global to refer to scope. What we are concerned about here is not just
global objects, but all objects which are defined outside of functions
(including, for example, static class members).

Quote:
Now reading your post, I am glad to hear that this seems to be wrong,
but I still wonder why the standard requires that the initialization
"shall occur before the first use of any function or object defined in
the same translation unit as the object to be initialized." I mean,
it does not matter when the object is initialized as long as it
happens before it is used, so why should it have to be initialized
before any other function or object is used?

Because it is impossible to implement? But then, of course, so is the
current rule. In practice, the actual rule is that all non-local
objects in statically linked modules will be initialized before main,
and all non-local objects in dynamically linked code will be initialized
when the dynamic object is loaded. In both cases, the order of
initialization is guaranteed within a module, but not between modules.

If you don't use dynamic linking, everything works according to the
standard; the right to defer initialization until after main has started
is not used. If you do use dynamic linking, and the constructor of a
non-local object in the dynamic object uses a non-local object in a
different module in the same dynamic object, all bets are off, even
though the standard says... But of course, if you use dynamic linking,
you are outside of the current standard anyway.

Quote:
Example:

// file1.cpp

#include "a.h";

A a;

// end file1.cpp

// file2.cpp

void f()
{
a.Use();
}

int main()
{
f();
}

// end file2.cpp

As you can see, the global object "a" is used in f(). However, f()
is not defined in the same translation unit as "a". Can anyone
point me to the relevant section of the standard that guarantees
that "a" will be initialized before it is used?

You've just quoted it. You are using the object a. That object is
defined in the translation unit file2. Initialization of all
objects in file2 must take place before the first use of a.

The object "a" is define din translation unit file1, and it is the one
and only object defined there. If Jack Klein should be right, there is
no guarantee that it will be initialized before it is used.

According to the standard, it is guaranteed. In this case, it is also
guaranteed in practice. Consider however the following:

A.cc:
#include <B.hh>

A a ;

A::A()
{
b.something() ;
}

B.cc:
#include <B.hh>

B b ;

void
B::something()
{
// supposes *this initialized.
}

main.cc

int
main()
{
a.something() ;
}

Now suppose that A.o and B.o are linked together into a dynamic object,
which is loaded on demand. (For this to be the case under Unix or
Windows, you would need to add code to explicitly load the module, look
up the address of a, etc. My code is just a sketch to give the idea.)
You've started main, so we are in the second case: initialization must
occur before the first use of any function or object in the same
translation unit. As far as I know, however, no implementation actually
guarantees this: the dynamic object (DLL in Windows, SO in Unix) will be
loaded, and the modules in it initialized in some arbitrary order --
although we have already entered main, module A could be initialized
before module B, in which case the constructor for module A will use an
uninitialized b.

But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Fri Dec 12, 2003 9:40 am    Post subject: Re: Confusion about 3.6.2/3 Reply with quote


<kanze (AT) gabi-soft (DOT) fr> schrieb in im Newsbeitrag:
[email]d6652001.0312110345.65eb07d4 (AT) posting (DOT) google.com[/email]...
Quote:
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message

[snip]

Quote:

Non-local objects can easily be used before they are initialized. By or
from constructors of other non-local objects. The only guarantees the
standard gives you is that non-local objects used after main has started
will be constructed, and that within a single translation unit,
non-local objects will be constructed in lexical order. If the
constructor of a non-local object uses another non-local object in a
different compilation unit, all bets are off.


What exactly does this mean, "in lexical order"? In the order of their
definition, or the order in which they are used? And which section of the
standard gives that guarantee?

[snip]

Quote:
Now suppose that A.o and B.o are linked together into a dynamic object,
which is loaded on demand. (For this to be the case under Unix or
Windows, you would need to add code to explicitly load the module, look
up the address of a, etc. My code is just a sketch to give the idea.)
You've started main, so we are in the second case: initialization must
occur before the first use of any function or object in the same
translation unit. As far as I know, however, no implementation actually
guarantees this: the dynamic object (DLL in Windows, SO in Unix) will be
loaded, and the modules in it initialized in some arbitrary order --
although we have already entered main, module A could be initialized
before module B, in which case the constructor for module A will use an
uninitialized b.

But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.


What is supposed to happen if the constructors of objects need each other,
like so:

A::A()
{
b.something();
}

B::B()
{
a.something();
}

In this case, it is obviously impossible to initialize each object before it
is used, and I could imagine someone (accidentally) writing code like this.
Is there anything the standard has to say about such a case?

Best regards,

Matthias Hofmann




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Francis Glassborow
Guest





PostPosted: Fri Dec 12, 2003 6:27 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

In article <brauhr$26s$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
<hofmann (AT) anvil-soft (DOT) com> writes
Quote:
Non-local objects can easily be used before they are initialized. By or
from constructors of other non-local objects. The only guarantees the
standard gives you is that non-local objects used after main has started
will be constructed, and that within a single translation unit,
non-local objects will be constructed in lexical order. If the
constructor of a non-local object uses another non-local object in a
different compilation unit, all bets are off.


What exactly does this mean, "in lexical order"? In the order of their
definition, or the order in which they are used? And which section of the
standard gives that guarantee?

The order of their definition see 3.6.2

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Randy Maddox
Guest





PostPosted: Sat Dec 13, 2003 2:21 am    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
kanze (AT) gabi-soft (DOT) fr> schrieb in im Newsbeitrag:
[email]d6652001.0312110345.65eb07d4 (AT) posting (DOT) google.com[/email]...
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message


[snip]


Quote:
What exactly does this mean, "in lexical order"? In the order of their
definition, or the order in which they are used? And which section of the
standard gives that guarantee?

In the order of their definition. See 3.6.2.

Quote:

[snip]

Now suppose that A.o and B.o are linked together into a dynamic object,
which is loaded on demand. (For this to be the case under Unix or
Windows, you would need to add code to explicitly load the module, look
up the address of a, etc. My code is just a sketch to give the idea.)
You've started main, so we are in the second case: initialization must
occur before the first use of any function or object in the same
translation unit. As far as I know, however, no implementation actually
guarantees this: the dynamic object (DLL in Windows, SO in Unix) will be
loaded, and the modules in it initialized in some arbitrary order --
although we have already entered main, module A could be initialized
before module B, in which case the constructor for module A will use an
uninitialized b.

But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.


What is supposed to happen if the constructors of objects need each other,
like so:

A::A()
{
b.something();
}

B::B()
{
a.something();
}

In this case, it is obviously impossible to initialize each object before it
is used, and I could imagine someone (accidentally) writing code like this.
Is there anything the standard has to say about such a case?

Best regards,

Matthias Hofmann


Don't do it. This is also addressed in 3.6.2.

Randy.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Dec 15, 2003 10:28 am    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote

Quote:
kanze (AT) gabi-soft (DOT) fr> schrieb in im Newsbeitrag:
[email]d6652001.0312110345.65eb07d4 (AT) posting (DOT) google.com[/email]...
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote in message

[snip]

Non-local objects can easily be used before they are initialized.
By or from constructors of other non-local objects. The only
guarantees the standard gives you is that non-local objects used
after main has started will be constructed, and that within a
single translation unit, non-local objects will be constructed in
lexical order. If the constructor of a non-local object uses
another non-local object in a different compilation unit, all bets
are off.

What exactly does this mean, "in lexical order"? In the order of their
definition, or the order in which they are used? And which section of
the standard gives that guarantee?

Lexical order means in the order the words appear; in this case, the
order that the compiler sees the declarations when reading the program
source. AS in §3.6.2/1: "Objects with static storage duration defined in
namespace scope in the same translation unit and dynamically initialized
shall be initialized in the order in which their definition appears in
the translation unit."

Quote:
[snip]

Now suppose that A.o and B.o are linked together into a dynamic
object, which is loaded on demand. (For this to be the case under
Unix or Windows, you would need to add code to explicitly load the
module, look up the address of a, etc. My code is just a sketch to
give the idea.) You've started main, so we are in the second case:
initialization must occur before the first use of any function or
object in the same translation unit. As far as I know, however, no
implementation actually guarantees this: the dynamic object (DLL in
Windows, SO in Unix) will be loaded, and the modules in it
initialized in some arbitrary order -- although we have already
entered main, module A could be initialized before module B, in
which case the constructor for module A will use an uninitialized
b.

But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.

What is supposed to happen if the constructors of objects need each
other, like so:

A::A()
{
b.something();
}

B::B()
{
a.something();
}

In this case, it is obviously impossible to initialize each object
before it is used, and I could imagine someone (accidentally) writing
code like this. Is there anything the standard has to say about such a
case?

If initialization occurs before the first instruction of main, it is
undefined behavior. (But attention, not all uses of an object before
dynamic initialization are undefined behavior.) If initialization
occurs after main, it is the case where the standard requires something
impossible.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Alf P. Steinbach
Guest





PostPosted: Mon Dec 15, 2003 3:43 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

On 11 Dec 2003 16:08:13 -0500, [email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:

Quote:
But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.

That is absurd. In your opinion then, the standard does not apply
to any program that makes use of anything outside the standard library.
In effect, the standard does not apply to real C++ programs.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Tue Dec 16, 2003 3:33 pm    Post subject: Re: Confusion about 3.6.2/3 Reply with quote

[email]alfps (AT) start (DOT) no[/email] (Alf P. Steinbach) wrote in message
news:<3fdd94a4.67761734 (AT) News (DOT) CIS.DFN.DE>...
Quote:
On 11 Dec 2003 16:08:13 -0500, [email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:

But of course, you have to use something non-standard to load the
dynamic library, so the standard doesn't apply anyway.

That is absurd. In your opinion then, the standard does not apply to
any program that makes use of anything outside the standard library.
In effect, the standard does not apply to real C++ programs.

Absurd or not, that's the way it is.

obviously, we expect standard conformance where the extensions don't
intersect with the standard, but the standard obviously has nothing to
say about this -- it is a quality of implementation issue. And it must
be interpreted with extreme caution:

- The standard guarantees that any number of names are in the user
namespace. Including non-standard headers (like <unistd.h> or
<windows.h>) is almost certain to invalidate this guarantee for some
names.

- With regards to the current question, if you call dlopen or
LoadLibrary, you are definitly in conflict with the standard, since
the standard talks of the phases of translation occuring before
execution. It's up to the implementation to define how this
interacts with the standard, what is still guaranteed, and what
isn't. In particular, most implementations will allow duplicate
definitions of some symbols, with well defined behavior, and almost
all will implement special rules concerning the initialization of
static objects. But the standard really has nothing to say about
this.

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.