Topic: Controlling order of construction for globals/statics
Author: kanze@gabi-soft.fr
Date: Wed, 23 Jul 2003 19:01:31 +0000 (UTC) Raw View
sebmol@yahoo.com ("Sebastian Moleski") wrote in message
news:<vhrq8qm6r3ck06@corp.supernews.com>...
> "Anders Dalvander" <google@dalvander.com> wrote in message
> news:d04c84a9.0307220901.6c2fe869@posting.google.com...
> > sebmol@yahoo.com ("Sebastian Moleski") wrote in message
> news:<vhoeti7dmusv49@corp.supernews.com>...
> > > IIRC, the initialization order of global variables in a
> > > translation unit is already defined as to happen in the order of
> > > declaration. So what are you asking for here?
> > OK, I wasn't very clear on my point. What if the three variables are
> > in three different files?
> The initialization order is not defined with respect to multiple
> translation units. One of the goals of C++ was to be able to use
> tools that already existed to take care of linking. It is possible to
> use a C++ compiler and a C linker to create exectuable files.
Not really. A C linker need not make any provision for dynamic
initialization of statics. Ever since the earliest CFront days, there
has always been a pre- or a post-linker to handle this. Today,
templates make even more demands.
> If the standard specified cross-unit initialization order, the linker
> would have to take care of part of that.
Certainly. Or if not the linker, the pre-linker or the post-linker.
The problem is the amount of information available. And where to find
that information -- I have a static variable a, whose constructor calls
a function f, which calls a function g, which makes use of a static
variable b; all of the static variables and all of the functions are in
different source files.
The languages I know which resolve this problem all have some form of
modules. Each module has a static initialization part, the compiler
makes a list of which other modules are used in this part, and the
linker does a topological sort based on this list. With C++ (and no
modules), the granularity would have to be based on the functions and
objects used; keeping a list of all of the functions and objects used in
every function and in every constructor represents a lot more
information to carry around.
> > Have anyone heard of any (next standard) way of controlling the
> > initialization order for that?
> Use a function to initialize it. Here's an example:
> // foo.h
> extern int& someGlobalVariable();
> // foo.cpp
> int& someGlobalVariable() {
> static int result = 12;
> return result;
> }
> Using the function, you get guaranteed initialization before the
> variable is access the first time. The only guarantee you have is that
> all variables are initialized before the first statement in main() is
> executed.
What you are proposing is the usual singleton pattern.
> > > Why would you want to change that?
> > I don't want to change anything that compiles and runs today, I wish
> > to add functionality of controlling the initialization order because
> > it is problematic the way it is right now (more or less random
> > between translation units).
> How would that work? C++ module dependency is not linear. You can have
> multiply circular dependencies that make it impossible to determine
> initialization order. To fix that, you would have to make a judgment
> call that turns those dependencies into a linear order.
No. If there are any cycles in the dependancy graph, it is an error,
and the code doesn't link.
> > What if static_value is depending of global_value? You cannot solve
> > that perfectly using C++98.
> In a way you can. Use the function-idiom I talked about earlier. You
> can make the variable be initialized by the return value of a function
> and store the return value of the function inside the function.
The singleton pattern doesn't help for static variables that are only
accessed through a container, and which are put into the container by
their constructor.
--
James Kanze GABI Software mailto:kanze@gabi-soft.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
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: google@dalvander.com (Anders Dalvander)
Date: Wed, 23 Jul 2003 19:01:37 +0000 (UTC) Raw View
sebmol@yahoo.com ("Sebastian Moleski") wrote in message news:<vhrq8qm6r3ck06@corp.supernews.com>...
> > Have anyone heard of any (next standard) way of controlling the
> > initialization order for that?
>
> Use a function to initialize it. Here's an example:
>
> // foo.h
> extern int& someGlobalVariable();
>
> // foo.cpp
> int& someGlobalVariable() {
> static int result = 12;
> return result;
> }
>
> Using the function, you get guaranteed initialization before the variable is
> access the first time. The only guarantee you have is that all variables are
> initialized before the first statement in main() is executed.
Sure I could use the Construct On First Use Idiom, but that ain't
foulproof either. If there are any other static/global objects whose
destructors might use someGlobalVariable() after
someGlobalVariable()::result is destructed, you're toast.
> > I don't want to change anything that compiles and runs today, I wish
> > to add functionality of controlling the initialization order because
> > it is problematic the way it is right now (more or less random between
> > translation units).
>
> How would that work? C++ module dependency is not linear. You can have multiply
> circular dependencies that make it impossible to determine initialization order.
> To fix that, you would have to make a judgment call that turns those
> dependencies into a linear order.
If you have circular dependencies, it is impossible to determine
initialization order, but if they are linear, it should be simple.
Somehow I would like to control the boxing of the construction and
destruction of the static/global objects. I don't have a good idea of
how this would be done, though.
> > What if static_value is depending of global_value? You cannot solve
> > that perfectly using C++98.
>
> In a way you can. Use the function-idiom I talked about earlier. You can make
> the variable be initialized by the return value of a function and store the
> return value of the function inside the function.
Sure, in a way I can solve it, by using the Construct On First Use
Idiom workaround. But as I wrote earlier, that ain't foulproof.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Mon, 28 Jul 2003 17:40:12 +0000 (UTC) Raw View
<kanze@gabi-soft.fr> wrote in message
news:d6652001.0307230342.3a7a692c@posting.google.com...
> > How would that work? C++ module dependency is not linear. You can have
> > multiply circular dependencies that make it impossible to determine
> > initialization order. To fix that, you would have to make a judgment
> > call that turns those dependencies into a linear order.
>
> No. If there are any cycles in the dependancy graph, it is an error,
> and the code doesn't link.
Um, two modules (and I mean object files which seem to be the most common
"modules" C++ implementations offer) can have references to objects in the
respective other module without any problems. The problem is, however, how to
determine which initialization should happen first.
sm
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: petebecker@acm.org (Pete Becker)
Date: Mon, 28 Jul 2003 17:40:48 +0000 (UTC) Raw View
kanze@gabi-soft.fr wrote:
>
> The languages I know which resolve this problem all have some form of
> modules. Each module has a static initialization part, the compiler
> makes a list of which other modules are used in this part, and the
> linker does a topological sort based on this list.
And then there's Java... It has a rather elaborate algorithm for lazy
dynamic initialization of static objects (they're statically initialized
to all zeros). The result is well defined, but rather brittle. I spent
several days getting the initialization order right in our Java library,
then got a bug report from a tester complaining that when he added a
print statement to something (I forget what) in that library it didn't
work right. His print statement triggered several premature
initializations, and the initialization code ended up seeing nulls
instead of constructed objects.
That's not a dig at Java (even though most of what I say about it is
<g>). Just a comment on how hard it is to do this without some sort of
rigid structure for initialization.
--
"To delight in war is a merit in the soldier,
a dangerous quality in the captain, and a
positive crime in the statesman."
George Santayana
"Bring them on."
George W. Bush
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: bop2@telia.com ("Bo Persson")
Date: Mon, 28 Jul 2003 17:41:23 +0000 (UTC) Raw View
"Anders Dalvander" <google@dalvander.com> skrev i meddelandet
> sebmol@yahoo.com ("Sebastian Moleski") wrote
>
> > How would that work? C++ module dependency is not linear. You can
have multiply
> > circular dependencies that make it impossible to determine
initialization order.
> > To fix that, you would have to make a judgment call that turns
those
> > dependencies into a linear order.
>
> If you have circular dependencies, it is impossible to determine
> initialization order, but if they are linear, it should be simple.
> Somehow I would like to control the boxing of the construction and
> destruction of the static/global objects. I don't have a good idea
of
> how this would be done, though.
>
My experience is with Ada-83 where this was solved by forbidding
circular dependencies. It was a compile time error!
The linker could then be given a preprocessed module list, in
initializaton order, with no forward references.
Probably wouldn't work very well for C++ though.
Bo Persson
bop2@telia.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: jeff.kish@mro.com (Jeff Kish)
Date: Tue, 29 Jul 2003 17:42:50 +0000 (UTC) Raw View
===================================== MODERATOR'S COMMENT:
Please don't overquote.
===================================== END OF MODERATOR'S COMMENT
On Mon, 21 Jul 2003 19:17:27 +0000 (UTC), sebmol@yahoo.com ("Sebastian Moleski") wrote:
>
>"Anders Dalvander" <google@dalvander.com> wrote in message
>news:d04c84a9.0307191457.23c59781@posting.google.com...
>> Has anyone posted/read a proposal for controlling the order of
>> construction for globals/statics in the next standard? Any suggestions
>> on how to control the following example to construct
>> foo::class_static_value, global_value and static_value in that order?
>
>IIRC, the initialization order of global variables in a translation unit is
>already defined as to happen in the order of declaration. So what are you asking
>for here? Why would you want to change that?
>
>sm
>
>
>---
>[ 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.jamesd.demon.co.uk/csc/faq.html ]
Could you tell me how long this has been the case? (I am using an old 5.0.2 Borland compiler, and would be interested to
know if it "obeys" this... it was supposed to be fairly compliant to the standard of its day.
Thanks
Jeff Kish
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: kanze@gabi-soft.fr
Date: Tue, 29 Jul 2003 17:42:54 +0000 (UTC) Raw View
sebmol@yahoo.com ("Sebastian Moleski") wrote in message
news:<vhu4odg9tono01@corp.supernews.com>...
> <kanze@gabi-soft.fr> wrote in message
> news:d6652001.0307230342.3a7a692c@posting.google.com...
> > > How would that work? C++ module dependency is not linear. You can
> > > have multiply circular dependencies that make it impossible to
> > > determine initialization order. To fix that, you would have to
> > > make a judgment call that turns those dependencies into a linear
> > > order.
> > No. If there are any cycles in the dependancy graph, it is an
> > error, and the code doesn't link.
> Um, two modules (and I mean object files which seem to be the most
> common "modules" C++ implementations offer) can have references to
> objects in the respective other module without any problems. The
> problem is, however, how to determine which initialization should
> happen first.
The problem is determining what the actual dependencies are, and I don't
think it is really feasable in C++. It's just to easy to follow
pointers, call virtual functions, etc., from the constructor, and end up
in modules that the compiler cannot see.
--
James Kanze GABI Software mailto:kanze@gabi-soft.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
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Tue, 29 Jul 2003 18:02:17 +0000 (UTC) Raw View
<kanze@gabi-soft.fr> wrote in message
news:d6652001.0307290622.3bd2586a@posting.google.com...
> > Um, two modules (and I mean object files which seem to be the most
> > common "modules" C++ implementations offer) can have references to
> > objects in the respective other module without any problems. The
> > problem is, however, how to determine which initialization should
> > happen first.
>
> The problem is determining what the actual dependencies are, and I don't
> think it is really feasable in C++. It's just to easy to follow
> pointers, call virtual functions, etc., from the constructor, and end up
> in modules that the compiler cannot see.
That's exactly my point. Fixing initialization order in the standard would
decrease a lot of the portability and adaptability C++ is known for and
developers rely on.
sm
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: google@dalvander.com (Anders Dalvander)
Date: Mon, 21 Jul 2003 18:32:08 +0000 (UTC) Raw View
Has anyone posted/read a proposal for controlling the order of
construction for globals/statics in the next standard? Any suggestions
on how to control the following example to construct
foo::class_static_value, global_value and static_value in that order?
(Replace int with your own favorite type.)
int global_value = ...;
static int static_value = ...;
class foo
{
static int class_static_value;
};
int foo::class_static_value = ...;
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Mon, 21 Jul 2003 19:17:27 +0000 (UTC) Raw View
"Anders Dalvander" <google@dalvander.com> wrote in message
news:d04c84a9.0307191457.23c59781@posting.google.com...
> Has anyone posted/read a proposal for controlling the order of
> construction for globals/statics in the next standard? Any suggestions
> on how to control the following example to construct
> foo::class_static_value, global_value and static_value in that order?
IIRC, the initialization order of global variables in a translation unit is
already defined as to happen in the order of declaration. So what are you asking
for here? Why would you want to change that?
sm
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: google@dalvander.com (Anders Dalvander)
Date: Wed, 23 Jul 2003 01:31:34 +0000 (UTC) Raw View
sebmol@yahoo.com ("Sebastian Moleski") wrote in message news:<vhoeti7dmusv49@corp.supernews.com>...
> IIRC, the initialization order of global variables in a translation unit is
> already defined as to happen in the order of declaration. So what are you asking
> for here?
OK, I wasn't very clear on my point. What if the three variables are
in three different files?
(Replace int with your own favorite type.)
File: a.cpp
int global_value = ...;
File: b.cpp
static int static_value = ...;
File: c.hpp
class foo
{
static int class_static_value;
};
File: c.cpp
#include "c.hpp"
int foo::class_static_value = ...;
Have anyone heard of any (next standard) way of controlling the
initialization order for that?
> Why would you want to change that?
I don't want to change anything that compiles and runs today, I wish
to add functionality of controlling the initialization order because
it is problematic the way it is right now (more or less random between
translation units).
What if static_value is depending of global_value? You cannot solve
that perfectly using C++98.
>
> sm
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sebmol@yahoo.com ("Sebastian Moleski")
Date: Wed, 23 Jul 2003 05:31:10 +0000 (UTC) Raw View
"Anders Dalvander" <google@dalvander.com> wrote in message
news:d04c84a9.0307220901.6c2fe869@posting.google.com...
> sebmol@yahoo.com ("Sebastian Moleski") wrote in message
news:<vhoeti7dmusv49@corp.supernews.com>...
> > IIRC, the initialization order of global variables in a translation unit is
> > already defined as to happen in the order of declaration. So what are you
asking
> > for here?
>
> OK, I wasn't very clear on my point. What if the three variables are
> in three different files?
The initialization order is not defined with respect to multiple translation
units. One of the goals of C++ was to be able to use tools that already existed
to take care of linking. It is possible to use a C++ compiler and a C linker to
create exectuable files. If the standard specified cross-unit initialization
order, the linker would have to take care of part of that.
> Have anyone heard of any (next standard) way of controlling the
> initialization order for that?
Use a function to initialize it. Here's an example:
// foo.h
extern int& someGlobalVariable();
// foo.cpp
int& someGlobalVariable() {
static int result = 12;
return result;
}
Using the function, you get guaranteed initialization before the variable is
access the first time. The only guarantee you have is that all variables are
initialized before the first statement in main() is executed.
> > Why would you want to change that?
>
> I don't want to change anything that compiles and runs today, I wish
> to add functionality of controlling the initialization order because
> it is problematic the way it is right now (more or less random between
> translation units).
How would that work? C++ module dependency is not linear. You can have multiply
circular dependencies that make it impossible to determine initialization order.
To fix that, you would have to make a judgment call that turns those
dependencies into a linear order.
> What if static_value is depending of global_value? You cannot solve
> that perfectly using C++98.
In a way you can. Use the function-idiom I talked about earlier. You can make
the variable be initialized by the return value of a function and store the
return value of the function inside the function.
sm
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]