Topic: static initialization


Author: "Tony" <gottlobfrege@gmail.com>
Date: Mon, 28 Feb 2005 11:06:46 CST
Raw View
   // at global file scope:
   int a = foo();
   int b = 15;
   int c = <sizeof or some other compile time thing>;
   int d = 0;
   int e;
   struct { int x, y; } f;


I know we can't rely on order of static initialization, but I'm
wondering about the constants, and the 'd'.  I completely assume that:

- e = f.x = f.y = 0
- b, c,... f are all set before foo() is called (even if b... are in
different files, etc)

Now, my only question is:

Do/Should I assume that because

a) the obvious implementation is that b...f are 'hardcoded' by the
compiler into the data segment (ie into the exe on disk), and the OS
just loads the datasegment into memory, so the numbers are 'already
there';

or

b) the standard says it must be so.

Tony.

---
[ 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: "Tony" <gottlobfrege@gmail.com>
Date: Mon, 28 Feb 2005 14:09:14 CST
Raw View
Tony wrote:
> I'm wondering about the constants, and the 'd'.

Kind of ignore that thing about the 'd'.  I added more variables after
writing that sentence, so I was probably really talking about e or f.
But it is a nearly useless statement anyhow.

---
[ 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: kuyper@wizard.net
Date: Thu, 3 Mar 2005 00:08:54 CST
Raw View
Tony wrote:
>    // at global file scope:
>    int a = foo();
>    int b = 15;
>    int c = <sizeof or some other compile time thing>;
>    int d = 0;
>    int e;
>    struct { int x, y; } f;
>
>
> I know we can't rely on order of static initialization, but I'm
> wondering about the constants, and the 'd'.  I completely assume
that:
>
> - e = f.x = f.y = 0

Correct.

> - b, c,... f are all set before foo() is called (even if b... are in
> different files, etc)

That depends upon what foo() is. The initialization of 'a' is called
dynamic initialization, not static initialization. The standard permits
dynamic initialization to be handled as static initialization under
certain circumstances. If the definition of foo() is in the same
translation unit, it's quite feasible for an implementation to
determine whether or not those conditions are met. The requirements
are:

3.6.2p2:
"An implementation is permitted to perform the initialization of an
object of namespace scope with static storage duration as a static
initialization even if such initialization is not requried to be done
statically, provided that

-- the dynamic version of the initialization does not change the value
of any other object of namespace scope with static storage duration
prior to its initialization, and

-- the static version of the initialization produces the same value in
the initialized object as would be produced by the dynamic
initialization if all objects not required to be initialized statically
were initialized dynamically.

It then gives an example of how this could be significant:

inline double fd() { return 1.0; }
extern double d1;
double d2 = d1;
double d1 = fd();

It's unspecified by the standard whether d2 gets initialized before or
after d1 gets initialized with a value of 1.0. If it happens before,
the value of d2 will be 0.0, not 1.0.

---
[ 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: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Thu, 3 Mar 2005 06:24:41 GMT
Raw View
Tony wrote:
>
>    // at global file scope:
>    int a = foo();
>    int b = 15;
>    int c = <sizeof or some other compile time thing>;
>    int d = 0;
>    int e;
>    struct { int x, y; } f;
>
>
> I know we can't rely on order of static initialization,

Actually, the ordering that's unspecified is that of *dynamic*
initialisation of non-local static variables, and then only between
translation units.

> but I'm wondering about the constants, and the 'd'.  I completely
> assume that:
>
> - e = f.x = f.y = 0
> - b, c,... f are all set before foo() is called (even if b... are in
> different files, etc)

This is correct.

> Now, my only question is:
>
> Do/Should I assume that because
>
> a) the obvious implementation is that b...f are 'hardcoded' by the
> compiler into the data segment (ie into the exe on disk), and the OS
> just loads the datasegment into memory, so the numbers are 'already
> there';
> or
>
> b) the standard says it must be so.

The standard says so; see 3.6.2/1.

--
Ben Hutchings
Power corrupts.  Absolute power is kind of neat.
                           - John Lehman, Secretary of the US Navy 1981-1987

---
[ 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: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 3 Mar 2005 06:24:51 GMT
Raw View
Tony wrote:
>    // at global file scope:
>    int a =3D foo();
>    int b =3D 15;
>    int c =3D <sizeof or some other compile time thing>;
>    int d =3D 0;
>    int e;
>    struct { int x, y; } f;
>=20
>=20
> I know we can't rely on order of static initialization, but I'm
> wondering about the constants, and the 'd'.  I completely assume that:
>=20
> - e =3D f.x =3D f.y =3D 0
> - b, c,... f are all set before foo() is called (even if b... are in
> different files, etc)
>=20
> Now, my only question is:
>=20
> Do/Should I assume that because
>=20
> a) the obvious implementation is that b...f are 'hardcoded' by the
> compiler into the data segment (ie into the exe on disk), and the OS
> just loads the datasegment into memory, so the numbers are 'already
> there';
>=20
> or
>=20
> b) the standard says it must be so.
>=20

It's b). Precisely it's in =A73.6.2/1:

"Objects with static storage duration (3.7.1) shall be zero-initialized=20
(8.5) before any other initialization takes place. Zero-initialization=20
and initialization with a constant expression are collectively called=20
static initialization; all other initialization is dynamic=20
initialization. Objects of POD types (3.9) with static storage
duration initialized with constant expressions (5.19) shall be=20
initialized before any dynamic initialization takes place. [...]"

BTW, it's not completely true that you can't rely on the order of static=20
initialization. Also in =A73.6.2/1 you can find a few guarantees:

"[...] Objects with static storage duration defined in namespace scope=20
in the same translation unit and dynamically initialized shall be=20
initialized in the order in which their definition appears in the=20
translation unit. [...]"

HTH,

Alberto

---
[ 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: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/27
Raw View
mjc@c1000907-b.sttls1.wa.home.com (Mark Crosland) writes:

>I have been looking through the most recent C++ ANSI/ISO standard. In
>partcular section 3.6.2, static initialization.

>I have been comparing this to what is in Stroustrups third edition on this
>topic.

> ...

>The standard seems pretty clear. Page 44 section 3.6.2 the part about dynamic
>initialization. The standard says it is implementation specific. I suppose one
>both or none could be registered with the pool.

Section 3.6.2 says the implementation can delay dynamic initialization
until after the first statement in main, which I think is your concern.
But it also says the initialization must happen before the first
use of any function or object defined in the same translation
unit as the delayed initialization.

The main reason for the loose restriction is to allow for dynamic
libraries. An object in a dynamic library can't be intitialized
until the library is loaded, and it might not be loadable until
after the program is running -- in resonse to some user command,
for example.

Except for dynamic libraries, implementations typically get all
non-local static objects initialized before the first statement
in main because it is convenient to do so, and is easier than
trying to do it at a later time. Except for dynamic libraries,
I don't know of an implementation that deliberately delays
inititalization.

But to be absolutely sure that your objects are registered in a
timely fashion, you should use some object or function in the
translation unit where the initialization occurs before you
depend on the registry.

>Stroustrup, page 217, 9.4.1, the first sentence says "In principle, ... is
>initialized before main()". Not sure what he meant by "In principle".

For example, some C++ implementations put a call to a function
that does the static initialization into main, ahead of any user-
written code.  You can't tell whether initialization happened before
main or via a function call in main.

--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: mjc@c1000907-b.sttls1.wa.home.com (Mark Crosland)
Date: 1999/09/25
Raw View
Hello,

I have been looking through the most recent C++ ANSI/ISO standard. In
partcular section 3.6.2, static initialization.

I have been comparing this to what is in Stroustrups third edition on this
topic.

I have three classes, 3 translation units. I would like each class, A and B to
register themselves in the pool before main() runs.

// pool.h
#include <vector>
class pool {

    public:
        static int swim(const char * id)
        {
            static bool firstTime = true;
            if (firstTime == true)
            {
                m_ids = new vector<const char *>;
            }

            m_ids->push_back(id);
            return 0;
        }
        static vector<const char *> * m_ids;

};

// this would more likely be in a cpp file?
vector<const char *> * pool::m_ids;

//////////////////////// A.cpp
// #include "pool.h"

static int sink = pool::swim("A");
class A { public: useA() {} };


//////////////////////// B.cpp
// #include "pool.h"

static int orSwim = pool::swim("B");
class B { public: useB() {} };


//////////////////////// main.cpp
int main()
{
    // at this point what IDs are in the pool?
    // A? B? none? both? implementation specific?
}

The standard seems pretty clear. Page 44 section 3.6.2 the part about dynamic
initialization. The standard says it is implementation specific. I suppose one
both or none could be registered with the pool.

Stroustrup, page 217, 9.4.1, the first sentence says "In principle, ... is
initialized before main()". Not sure what he meant by "In principle".

Another section from Stroustrup, page 252, section 10.4.9, the first sentence
says basically the same thing, but without the phrase "In principle". hmmm...

I am not concerned about order, just that everything gets registered with the
pool before we get to main().

I have tried this scenarion out with egcs-1.1.2 and HP aCC A.03.10 and
everything seems to get initialized before main(). I can't find any
documentation for either compiler that either confirms or refutes the
consistency of this behaviour.

Thought, opinions?

Thanks,
Mark Crosland
mjc@c1000907-b.sttls1.wa.home.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]