Topic: Initialization of unused static objects


Author: "Piotr Dobrogost" <pbc@poczta.onet.pl>
Date: Sun, 2 Sep 2001 11:17:16 GMT
Raw View
"Francis Glassborow" <francis.glassborow@ntlworld.com> wrote in message
news:p39vRYC2WkR7EwbJ@ntlworld.com...
> In article <3B461A60.491A91FF@akella.com>, Igor A. Goussarov
> <igusarov@akella.com> writes
> >   Thus, an ability to defer global static object initialization imposes
> >a possible change in observable behavior and even possible undefined
> >behavior. And is it a fair price to pay? What can one gain from this
> >defered initialization?
> My point is that it is possible to force initialisation if you need to,
> just include a vacuous function in each problem TU that is called from
> main (as part of initialising an object in the TU containing main. If

But the whole thing is to have static objects in filescope (namespace scope
? don't know  difference) initialized _before_ main(). This way we can add
new code by simple linking main program (in object file) with new modules
(in object files) adding extra functionality. Having to change main() makes
whole idea useless.
I think that's what Igor had in mind when he was writing this:

"From my point of view the global static objects (those ones that look
unused) might have an intent to perform some kind of pre-main
initialization. E.g. to register a factories, to register streamable
classes signatures, to initialize the logging system, etc. In other
words they can do something that is good to be performed when the proper
library is linked to the project, without any requirements to change
main() in order to call such initialization explicitly."

I've read whole thread and still don't know weather static objects in
filescope must be initialized before main() or not. Someone knows ?

Piotr Dobrogost


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: agriff@tin.it (Andrea Griffini)
Date: Sun, 2 Sep 2001 18:23:29 GMT
Raw View
On Sun,  2 Sep 2001 11:17:16 GMT, "Piotr Dobrogost"
<pbc@poczta.onet.pl> wrote:

>I've read whole thread and still don't know weather static objects in
>filescope must be initialized before main() or not. Someone knows ?

The standard says that the initialization may be delayed until
a function or object in the compilation unit is referred to.
So, unfortunately, this means that you can't use a static object
as a sort of "atstart" (opposite of "atexit"); at least not in
a portable way.

I've found that things normally work as you expect them to if
you're just linking normal object files. I've heard that even
using just static libraries may not work because many linkers
just drop an module in a library unless there is someone from
the extern of it referencing it (and that's in my opinion a
pretty reasonable behaviour).

Of course you can't pretend to have static instances
initialized before entering main for objects in dynamically
loaded libraries: how can you pretend the C++ runtime system
to initialize an object that resides in a library that will
be loaded only later (if loaded at all) ?

If I understood the issue correctly, the reason for that wording
of the standard is exactly to allow a C++ program to use some
form of dynamic code loading: saying that every static object
must be constructed before entering main would mean that no
C++ code with static objects may exist in a library loaded
dynamically after main is entered.

Andrea

--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Igor A. Goussarov" <igusarov@akella.com>
Date: Tue, 10 Jul 2001 16:34:14 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3B49BD41.427D6D57@akella.com>, Igor A. Goussarov
> <igusarov@akella.com> writes
> >   BTW, what you said about DLLs is a bit strange. If I don't need some
> >DLL I will not link it to my program. But if I have linked the said
> >DLL then it is a sign that I need it used... The idea to link the
> >program with all possible libraries and make a linker decide which of
> >them are used will not do me any good (IMHO).
>
> But one reason for using DLLs is that the need to use the code can only
> be determined at execution time.

   And can this lead to ignoring the rule that even unused static object
of namespace scope should be initialized?

Igor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: jk@steel.orel.ru (Eugene Karpachov)
Date: Wed, 11 Jul 2001 17:00:11 GMT
Raw View
Mon,  9 Jul 2001 20:05:34 GMT Francis Glassborow wrote:
>In article <3B49BD41.427D6D57@akella.com>, Igor A. Goussarov
><igusarov@akella.com> writes
>>DLL I will not link it to my program. But if I have linked the said
>>DLL then it is a sign that I need it used... The idea to link the
>>program with all possible libraries and make a linker decide which of
>>them are used will not do me any good (IMHO).
>
>But one reason for using DLLs is that the need to use the code can only
>be determined at execution time.

To load DLL dynamically is not the same thing as to link DLL to program with
linker.

--
jk

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "C. M. Heard" <heard@vvnet.com>
Date: Wed, 11 Jul 2001 17:00:28 GMT
Raw View
Igor A. Goussarov wrote:
>    Oh, no, I should pay for its existence! Look, if I have a translation
> unit (maybe DLL) linked to my project and it has a static object of
> namespace scope then it _has_ to be constructed even if it seems unused
> (footnote 31, 3.7.1-2), particulary even if the whole DLL seems unused.
> I believe this requirement do has some reason. And this requirement
> contradicts with the rest of 3.6.2-3, which allow the compiler to defer
> the initialization until the object (or any other member of that TU) is
> first time used. Being applied to the object that is _never_ used, this
> rule may lead to a funny conclusion: the said object might be
> constructed e.g. just before the program terminates. You see, whatever
> that reasons for asking a compiler to initialize even an unused object
> are, they are completely nullified by the ability to initialize this
> object when such initialization is already meaningless. I mean, if this
> object was not constructed during the execution of main() than it is
> effectively the same asif it was not constructed at all. Thus defered
> construction does not respect the reasons why the initialization of
> unused objects is required. Am I missing some point here?

Actually, under my reading, the situation is even worse:  the way I read
the following paragraph, an implementation is permitted to defer
initialization of an object _indefinitely_ unless it is used or some
function or object in the same translation is used.  It seems to me that
the requirement (in the footnote cited below and also in 3.7.1) to
initialize unused objects whose initialization has side effects
applies only to objects that reside in a TU where some function is called
or some other object is explicitly referenced.

  3.6.2 Initialization of non-local objects             [basic.start.init]
  [ ... ]
  It is implementation-defined whether or not the dynamic initialization
  (8.5, 9.4, 12.1, 12.6.1) 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. 31)
  [ ... ]
  __________________
  31) An object defined in namespace scope having initialization with
  side-effects must be initialized even if it is not used (3.7.1).

In other words (if I read this correctly) an implementation is required
to faithfully reproduce _the side-effects of initialization_ of unused
namespace objects, but only for such objects that reside in a TU where
some function or some other object is used.

>    From my point of view the global static objects (those ones that look
> unused) might have an intent to perform some kind of pre-main
> initialization. E.g. to register a factories, to register streamable
> classes signatures, to initialize the logging system, etc. In other
> words they can do something that is good to be performed when the proper
> library is linked to the project, without any requirements to change
> main() in order to call such initialization explicitly.

I've used pre-main initialization of global static objects to implement
automatic construction of managed object databases, and so I fully
appreciate how useful of this technique can be.

You (and I) can at least take some comfort in the fact that it is
implementation defined (and not undefined) whether or not initialization
of global static objects occurs before the first statement of main.
That means that an implementation must document what it does.

The implementations with which I have experience all guarantee that
initialization of global static objects will take place before the
first statement of main if they reside in statically-linked modules.
The same guarantee is not offered for shared libraries or DLLs, where
initialization typically takes place when the library is loaded
(either explicitly or on first use of some object or function therein).
And in cases where the static objects are not explicitly referenced
you'll typically need to put them in stand-alone .o files and not in
static libraries.  None of this is covered by the standard, but it
should be covered by your implementation's documentation.

Hope that helps.

Mike

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Wed, 11 Jul 2001 17:00:24 GMT
Raw View
In article <3B4B2E62.EEEA7920@akella.com>, Igor A. Goussarov
<igusarov@akella.com> writes
>> But one reason for using DLLs is that the need to use the code can only
>> be determined at execution time.
>
>   And can this lead to ignoring the rule that even unused static object
>of namespace scope should be initialized?

In practice? Almost certainly yes. Of course the Standard has nothing to
say about DLLs but that does not mean the writers of the Standard
ignored them.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Igor A. Goussarov" <igusarov@akella.com>
Date: Thu, 12 Jul 2001 13:08:14 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3B4B2E62.EEEA7920@akella.com>, Igor A. Goussarov
> <igusarov@akella.com> writes
> >> But one reason for using DLLs is that the need to use the code can only
> >> be determined at execution time.
> >
> >   And can this lead to ignoring the rule that even unused static object
> >of namespace scope should be initialized?
>
> In practice? Almost certainly yes. Of course the Standard has nothing to
> say about DLLs but that does not mean the writers of the Standard
> ignored them.

   Technicaly, if the DLLs are loaded and linked at a program startup
(before dynamic initialization or even before static initialization took
place) then the constructors of dynamically initialized global objects
and main() don't have to be able to distinguish between statically and
dynamically linked libraries. And the rules in question are applicable
to DLLs as well as to ordinal libraries.
   Dynamic linking is performed by some kind of OS precess management
system and is out of language's control. But I have no doubts that the
program startup code have an ability to determine the set of DLLs that
were loaded along with the program and initialize them all immediately,
before main() is called. Yes, this initialization is a subject to static
initialization order fiasco, as well as initialization of static objects
from non-dynamic libraries. But this is better then bypassing the
initialization at all.

   If you were talking about run-time loading of the DLL (via dlopen()
or LoadLibrary() or whatever) then of course, global objects in those
DLLs have no chance to be initialized before main(). From the point of
common sense such objects should be initialized before the
aforementioned OS loading functions return, but the standard doesn't
cover this issue. In any way ignoring the object initialization is not
good solution to the problem of dynamic linking because it affects the
semantic of the program.

Igor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Igor A. Goussarov" <igusarov@akella.com>
Date: Fri, 6 Jul 2001 17:52:50 GMT
Raw View
Hello!

   The standard requires that objects of namespace scope with static
storage duration must be initialized either before main() is entered or
before the said object is first time used. And the standard explicitly
states that such objects of namespace scope (initialization of which is
accompanied by side effects) should be initialized even if they are
unused.
   Combining these two requirements one might conclude that it is legal
to initialize the aforementioned unused static objects for example right
before the program terminates. Just when exit() is called, such object
is constructed and then immediately destructed. Is it a correct
conclusion? Is an implementation permitted to do behave that way?
   From my point of view the global static objects (those ones that look
unused) might have an intent to perform some kind of pre-main
initialization. E.g. to register a factories, to register streamable
classes signatures, to initialize the logging system, etc. In other
words they can do something that is good to be performed when the proper
library is linked to the project, without any requirements to change
main() in order to call such initialization explicitly.

Igor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Fri, 6 Jul 2001 18:53:46 GMT
Raw View
In article <3B457403.A1D79ADE@akella.com>, Igor A. Goussarov
<igusarov@akella.com> writes
>   From my point of view the global static objects (those ones that look
>unused) might have an intent to perform some kind of pre-main
>initialization. E.g. to register a factories, to register streamable
>classes signatures, to initialize the logging system, etc. In other
>words they can do something that is good to be performed when the proper
>library is linked to the project, without any requirements to change
>main() in order to call such initialization explicitly.

I think there is a requirement for initialisation of all
global/file/namespace scope data prior to any call of a function defined
in the same translation unit.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Igor A. Goussarov" <igusarov@akella.com>
Date: Fri, 6 Jul 2001 20:27:21 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3B457403.A1D79ADE@akella.com>, Igor A. Goussarov
> <igusarov@akella.com> writes
> >   From my point of view the global static objects (those ones that look
> >unused) might have an intent to perform some kind of pre-main
> >initialization. E.g. to register a factories, to register streamable
> >classes signatures, to initialize the logging system, etc. In other
> >words they can do something that is good to be performed when the proper
> >library is linked to the project, without any requirements to change
> >main() in order to call such initialization explicitly.
>
> I think there is a requirement for initialisation of all
> global/file/namespace scope data prior to any call of a function defined
> in the same translation unit.

   Right. But your correction doesn't invalidate the question. I can
easily imagine the situations when _no_ function or object from that
translation unit is called or used. E.g. an application may consist of
main module and a lot of statically linked modules (== translation
units); each of them has a static object which is entitled to register
some factory (defined and implemented in this unit) in the global
registry. Then the user is presented with a list of available features,
functions or whatever. In this case, main module know nothing about the
others. It doesn't call any function from those modules because it
doesn't know about their existence, unless they have registered
themselves during program startup. And the ability to defer the
initialization of namespace static objects makes this behavior rather
unreliable. Is it intended? Why and what for?
   Another example is the situation when some static object is defined
in one translation unit while another translation unit have a global
static pointer initialized with an address of those object. If I use
this pointer before any function from the first module, I can easily
find myself using an unititialized object.
   Thus, an ability to defer global static object initialization imposes
a possible change in observable behavior and even possible undefined
behavior. And is it a fair price to pay? What can one gain from this
defered initialization?

Igor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Sat, 7 Jul 2001 05:40:37 GMT
Raw View
In article <3B461A60.491A91FF@akella.com>, Igor A. Goussarov
<igusarov@akella.com> writes
>   Thus, an ability to defer global static object initialization imposes
>a possible change in observable behavior and even possible undefined
>behavior. And is it a fair price to pay? What can one gain from this
>defered initialization?
My point is that it is possible to force initialisation if you need to,
just include a vacuous function in each problem TU that is called from
main (as part of initialising an object in the TU containing main. If
IIUC the reason for the rule is to allow such things as DLLs, if you do
not call a function from a DLL, you do not pay for its existence.

Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Igor A. Goussarov" <igusarov@akella.com>
Date: Mon, 9 Jul 2001 15:54:21 GMT
Raw View
Francis Glassborow wrote:
>
> In article <3B461A60.491A91FF@akella.com>, Igor A. Goussarov
> <igusarov@akella.com> writes
> >   Thus, an ability to defer global static object initialization imposes
> >a possible change in observable behavior and even possible undefined
> >behavior. And is it a fair price to pay? What can one gain from this
> >defered initialization?
> My point is that it is possible to force initialisation if you need to,
> just include a vacuous function in each problem TU that is called from
> main (as part of initialising an object in the TU containing main. If
> IIUC the reason for the rule is to allow such things as DLLs, if you do
> not call a function from a DLL, you do not pay for its existence.

   Oh, no, I should pay for its existence! Look, if I have a translation
unit (maybe DLL) linked to my project and it has a static object of
namespace scope then it _has_ to be constructed even if it seems unused
(footnote 31, 3.7.1-2), particulary even if the whole DLL seems unused.
I believe this requirement do has some reason. And this requirement
contradicts with the rest of 3.6.2-3, which allow the compiler to defer
the initialization until the object (or any other member of that TU) is
first time used. Being applied to the object that is _never_ used, this
rule may lead to a funny conclusion: the said object might be
constructed e.g. just before the program terminates. You see, whatever
that reasons for asking a compiler to initialize even an unused object
are, they are completely nullified by the ability to initialize this
object when such initialization is already meaningless. I mean, if this
object was not constructed during the execution of main() than it is
effectively the same asif it was not constructed at all. Thus defered
construction does not respect the reasons why the initialization of
unused objects is required. Am I missing some point here?

   BTW, what you said about DLLs is a bit strange. If I don't need some
DLL I will not link it to my program. But if I have linked the said
DLL then it is a sign that I need it used... The idea to link the
program with all possible libraries and make a linker decide which of
them are used will not do me any good (IMHO).

Igor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 9 Jul 2001 20:05:34 GMT
Raw View
In article <3B49BD41.427D6D57@akella.com>, Igor A. Goussarov
<igusarov@akella.com> writes
>   BTW, what you said about DLLs is a bit strange. If I don't need some
>DLL I will not link it to my program. But if I have linked the said
>DLL then it is a sign that I need it used... The idea to link the
>program with all possible libraries and make a linker decide which of
>them are used will not do me any good (IMHO).

But one reason for using DLLs is that the need to use the code can only
be determined at execution time.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]