f



'static initialization' vs. 'dynamic initialization'

What are the definitions of 'static initialization' and 'dynamic
initialization'? Does 'static initialization', mean "compile/link time
rather than run time" whereas 'dynamic initialization' is the converse? Is
'dynamic initialization' mean everything that is initialized before main()
is entered but after compile/link time?

My confusion stems from the following excerpt from "The Design and 
Evolution
of C++" (1994) by B. Stroustrup, pg. 96:

"Such initialization cannot in general be done completely a compile time or
at link time. Dynamic (run-time) initialization is necessary. Dynamic
initialization is done in declaration order within a translation unit. No
order is defined for initialization of objects in different translation
units except that all static initialization takes place before any dynamic
initialization."

The first two sentences of quote imply that "static initialization" is done
at compile/link time, which makes the last part of the last sentence of the
quote a big "duh!": "all static initialization takes place before any
dynamic initialization." Or did he mean that objects declared with the
'static' keyword are initialized before those that aren't?

John


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

0
JohnQ
2/14/2007 6:17:25 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

16 Replies
1428 Views

Similar Articles

[PageSpeed] 17

JohnQ wrote:

> Or did he mean that objects declared with the
> 'static' keyword are initialized before those that aren't?

Note that static initialization applies not only to those objects that
are declared with 'static' keyword, but to those that have static
storage duration in general - this includes global objects.

Static initialization applies to those objects that have static storage
duration and can be done as either zero-initialization or initialization
with constant expression. In both cases the initialization takes place
before any dynamic initialization in the program.

Note also that static initialization is not necessarily compile-time.
Consider a big global array:

int bigArray[10000000];

On the machine where int is 32 bits initializing this array at compile
time would require putting some 40MB of zeros in the executable, which
would be just wasteful. Today linkers don't do this and instead the
array is created and cleared at the time the program is loaded into
memory. This is no longer compile-time, but still before any dynamic
initialization, as the standard requires.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/

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

0
Maciej
2/15/2007 5:49:12 AM
JohnQ wrote:
> What are the definitions of 'static initialization' and 'dynamic
> initialization'?

Formally, zero-initialization and initialization of a POD with a
constant expression (or constant expressions) is called static
initialization, everything else is dynamic.  All static
initialization occurs before any dynamic initialization (and the
fact that the initializers are constant expressions means that
there can be no ordering dependancies in static initialization).

> Does 'static initialization', mean "compile/link time
> rather than run time" whereas 'dynamic initialization' is the converse?

More or less.  The standard doesn't delve into such
implementation details, but in all of the compilers I'm familiar
with, static initialization becomes part of the loaded process
image, much like generated code.

> Is
> 'dynamic initialization' mean everything that is initialized before main()
> is entered but after compile/link time?

There's no guarantee in the standard that it will be initialized
before main is entered, but in practice, yes, except for
dynamically loaded components.  Conceptually, the simplest way
to think of it is that static initialization is read from the
disk when the program is started, where as dynamic
initialization involves the execution of instructions in the
loaded process.

> My confusion stems from the following excerpt from "The Design and
> Evolution
> of C++" (1994) by B. Stroustrup, pg. 96:

> "Such initialization cannot in general be done completely a compile time or
> at link time. Dynamic (run-time) initialization is necessary. Dynamic
> initialization is done in declaration order within a translation unit. No
> order is defined for initialization of objects in different translation
> units except that all static initialization takes place before any dynamic
> initialization."

> The first two sentences of quote imply that "static initialization" is done
> at compile/link time, which makes the last part of the last sentence of the
> quote a big "duh!":

Sort of.  Except that it deliniates an important exception to
the first part of the sentence.

> "all static initialization takes place before any
> dynamic initialization." Or did he mean that objects declared with the
> 'static' keyword are initialized before those that aren't?

Static is a very overloaded word, both as a keyword and in
general use:-).  The static in static initialization has nothing
to do with the keyword.  What is being discussed is the
initialization of non-local objects with static storage
duration, i.e. objects defined at namespace scope (with or
without the static keyword).  Such initialization can be
considered to be broken down into three phases:
zero-initialization, constant-initialization and dynamic
initialization.  Conceptually, they occur in that order,
although because there is no way in constant-initialization to
determine whether zero-initialization has taken place, most
implementations merge these two steps, and in many contexts, the
standard as well treats them as one, under the name
static-initialization.

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



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

0
James
2/15/2007 10:08:30 AM
"Maciej Sobczak" <no.spam@no.spam.com> wrote in message
news:er13pk$f80$1@cernne03.cern.ch...
> JohnQ wrote:
>
>> Or did he mean that objects declared with the
>> 'static' keyword are initialized before those that aren't?
>
> Note that static initialization applies not only to those objects that
> are declared with 'static' keyword, but to those that have static
> storage duration in general - this includes global objects.
>
> Static initialization applies to those objects that have static storage
> duration and can be done as either zero-initialization or initialization
> with constant expression. In both cases the initialization takes place
> before any dynamic initialization in the program.

I used 'objects' to mean 'instances of a class' rather than the more 
general
way that 'objects' could be used. I'm still quite confused about "static
storage duration" vs. "class objects declared with the static keyword" vs.
"static vs. dynamic initialization". For instance, is a constructor
initialization list part of "dynamic initialization"?

John


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

0
JohnQ
2/15/2007 6:47:54 PM
"James Kanze" <james.kanze@gmail.com> wrote in message
news:1171536438.699419.123660@j27g2000cwj.googlegroups.com...
> JohnQ wrote:
>> What are the definitions of 'static initialization' and 'dynamic
>> initialization'?
>
> Formally, zero-initialization and initialization of a POD with a
> constant expression (or constant expressions) is called static
> initialization, everything else is dynamic.

Now _that_ is a definition I can assimilate. I was getting confused on 
how a
class object instance could be considered part of static initialization 
when
constructors have to run to initialize the object.

> All static
> initialization occurs before any dynamic initialization (and the
> fact that the initializers are constant expressions means that
> there can be no ordering dependancies in static initialization).

Do you mean that ordering dependency has to be avoided or that it is
impossible?

>> Does 'static initialization', mean "compile/link time
>> rather than run time" whereas 'dynamic initialization' is the converse?
>
> More or less.  The standard doesn't delve into such
> implementation details, but in all of the compilers I'm familiar
> with, static initialization becomes part of the loaded process
> image, much like generated code.

OK, good.

>> Is
>> 'dynamic initialization' mean everything that is initialized before 
>> main()
>> is entered but after compile/link time?
>
> There's no guarantee in the standard that it will be initialized
> before main is entered, but in practice, yes, except for
> dynamically loaded components.  Conceptually, the simplest way
> to think of it is that static initialization is read from the
> disk when the program is started, where as dynamic
> initialization involves the execution of instructions in the
> loaded process.

OK, good.

>> My confusion stems from the following excerpt from "The Design and
>> Evolution
>> of C++" (1994) by B. Stroustrup, pg. 96:
>
>> "Such initialization cannot in general be done completely a compile time 
>> or
>> at link time. Dynamic (run-time) initialization is necessary. Dynamic
>> initialization is done in declaration order within a translation unit. No
>> order is defined for initialization of objects in different translation
>> units except that all static initialization takes place before any 
>> dynamic
>> initialization."
>
>> The first two sentences of quote imply that "static initialization" is 
>> done
>> at compile/link time, which makes the last part of the last sentence of 
>> the
>> quote a big "duh!":
>
> Sort of.  Except that it deliniates an important exception to
> the first part of the sentence.

I think "No order is defined for DYNAMIC initialization of objects in
different translation units" would have sufficed.

>> "all static initialization takes place before any
>> dynamic initialization." Or did he mean that objects declared with the
>> 'static' keyword are initialized before those that aren't?
>
> Static is a very overloaded word, both as a keyword and in
> general use:-).

Indeed. One of the subtleties that makes learning the language difficult.

> The static in static initialization has nothing
> to do with the keyword.  What is being discussed is the
> initialization of non-local objects with static storage
> duration, i.e. objects defined at namespace scope (with or
> without the static keyword).

"globals" pretty much, yes?

> Such initialization can be
> considered to be broken down into three phases:
> zero-initialization, constant-initialization and dynamic
> initialization.  Conceptually, they occur in that order,
> although because there is no way in constant-initialization to
> determine whether zero-initialization has taken place, most
> implementations merge these two steps, and in many contexts, the
> standard as well treats them as one, under the name
> static-initialization.

OK, good explanation. I get it. I was wondering overall if there was 
such an
animal as static initialization of class object instances at "global"
(namespace) scope. I was/am investigating the
order-of-initialization-of-global-class-objects problem and was wondering
what the solutions were that didn't cause a bunch of paging at program
startup and termination. Common Singleton techniques appear to cause the
paging problem (not that I've noticed it, just that I've read about it in
D&E).

John


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

0
JohnQ
2/15/2007 6:48:31 PM
JohnQ wrote:

> I used 'objects' to mean 'instances of a class' rather than the more 
> general
> way that 'objects' could be used.

"Instances of a class" can have static storage duration without being 
declared with the 'static' keyword - it's enough if they are global.

> I'm still quite confused about "static
> storage duration" vs. "class objects declared with the static keyword" vs.
> "static vs. dynamic initialization". For instance, is a constructor
> initialization list part of "dynamic initialization"?

Yes. The initialization list in its entirety is not a constant 
expression (even if each component in the list if initialized by 
constant expression) and as such is not performed statically.
If the given object has static storage duration, its constructor is 
literally executed, and is not magically "given" by the 
compiler/linker/loader/etc. Now, *when* this constructor is executed 
depends on how the object was declard - if it's a static local object 
inside some function, then it's constructed the first time its 
declaration is encountered; and some time before the first explicit 
statement in function main otherwise.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/

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

0
Maciej
2/16/2007 7:21:10 AM
JohnQ wrote:
> "James Kanze" <james.kanze@gmail.com> wrote in message
> news:1171536438.699419.123660@j27g2000cwj.googlegroups.com...
> > JohnQ wrote:
> >> What are the definitions of 'static initialization' and 'dynamic
> >> initialization'?

> > Formally, zero-initialization and initialization of a POD with a
> > constant expression (or constant expressions) is called static
> > initialization, everything else is dynamic.

> Now _that_ is a definition I can assimilate. I was getting
> confused on how a class object instance could be considered
> part of static initialization when constructors have to run to
> initialize the object.

If the constructors are trivial, there's no problem.  (User
defined constructors are not trivial, by definition.)

> > All static
> > initialization occurs before any dynamic initialization (and the
> > fact that the initializers are constant expressions means that
> > there can be no ordering dependancies in static initialization).

> Do you mean that ordering dependency has to be avoided or that it is
> impossible?

Anything which would create a dependancy will in fact prevent
the expression from being constant.  Constant expressions are
evaluated by the compiler, and so cannot depend on the execution
of other code.  (If you use a const variable of integral type,
whose initializer is an integral constant expression, in the
initialization expression, the initialization expression could
be said to depend on that variable.  Of course, in order to do
this, the variable must have been defined and initialized
previously in the translation unit, which means that the order
of initialization would be guaranteed.  But I think it is even
more accurate to say that what is used is not the variable, but
the value it is initialized with, so again, there is no
dependancy.)

Note that a compiler is allowed, under certain circumstances, to
replace dynamic initialization with static.  If, for example,
the constructors for std::complex<double> are inline (probably
the case), and you write something like:

    std::complex< double > z( 1.2, 3.4 ) ;

the compiler is allowed to generate static initialization, as if
complex were a PODS, with no constructors and you had written:

    std::complex< double > z = { 1.2, 3.4 } ;

Most of the time, a program won't be able to tell, but there are
exceptions.

      [...]
> > The static in static initialization has nothing
> > to do with the keyword.  What is being discussed is the
> > initialization of non-local objects with static storage
> > duration, i.e. objects defined at namespace scope (with or
> > without the static keyword).

> "globals" pretty much, yes?

Not really.  At least, not only:

    int x = f() ;           //  global.
    static int y = f() ;    //  global?
    namespace {
        int z = f() ;       //  global?
    }

The standard doesn't define or use the term globals; it speaks
in terms of object lifetime and linkage.  In the above, I would
normally only speak of the first as global, although one might
argue about the third.  All have static lifetime, however.  (In
the terms of the standard, the first has external linkage and the
second internal linkage; the third has external linkage, but
cannot be named in another translation unit.)

There is also a question about local variables with static
storage duration, e.g.

    void
    f()
    {
        static int i = 42 ;
    }

According to the standard, these are initialized when the
definition is first encountered during execution, regardless of
whether the initialization is a constant expression or not.  In
practice, however, if the initialization would qualify for
static initialization at namespace scope, there's no way a
program can tell if it takes place earlier, and all of the
implementations I know also initialize the variable from the
loaded process image, exactly as they do for variables at
namespace scope.  (This is only true for static initialization,
however; any dynamic initialization will not be done until the
definition is reached.)

> > Such initialization can be
> > considered to be broken down into three phases:
> > zero-initialization, constant-initialization and dynamic
> > initialization.  Conceptually, they occur in that order,
> > although because there is no way in constant-initialization to
> > determine whether zero-initialization has taken place, most
> > implementations merge these two steps, and in many contexts, the
> > standard as well treats them as one, under the name
> > static-initialization.

> OK, good explanation. I get it. I was wondering overall if
> there was such an animal as static initialization of class
> object instances at "global" (namespace) scope.

Sure:

    struct Toto
    {
        int a ;
        int b ;
    } ;

    Toto x = { -1, 42 } ;

Static initialization of an object with class type at namespace
scope.  The critical part related to the type is that the object
must be a POD; POD structs (which have class type) can be
initialized statically, just like any other POD.

Note that anything which prevents POD-ness prevents static
initialization.  Any user defined constructor, obviously, but
also any private or protected non-static data members, any
virtual functions, any base classes, a user defined assignment
operator or a user defined destructor.

> I was/am investigating the
> order-of-initialization-of-global-class-objects problem and was wondering
> what the solutions were that didn't cause a bunch of paging at program
> startup and termination. Common Singleton techniques appear to cause the
> paging problem (not that I've noticed it, just that I've read about it in
> D&E).

How does the usual singleton idiom cause paging?  I think you're
thinking of the tricky counter idiom, which is relatively little
used today.

Order of initialization can be a serious problem, however, and
one of the main reasons I sometimes use C style arrays instead
of std::vector is precisely to obtain static initialization, and
avoid order of initialization problems.  (Similarly, I'll use a
presorted C style array and std::lower_bound rather than
std::map or std::set for constant objects with static lifetime,
in order to avoid order of initialization problems.)

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orientie objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, France, +33 (0)1 30 23 00 34



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

0
James
2/16/2007 7:57:24 AM
"James Kanze" <james.kanze@gmail.com> wrote in message 
news:1171619989.995661.215400@q2g2000cwa.googlegroups.com...
> JohnQ wrote:

>> I was/am investigating the
>> order-of-initialization-of-global-class-objects problem and was wondering
>> what the solutions were that didn't cause a bunch of paging at program
>> startup and termination. Common Singleton techniques appear to cause the
>> paging problem (not that I've noticed it, just that I've read about it in
>> D&E).
>
> How does the usual singleton idiom cause paging?

By scattering initialization/termination code throughout an application 
program?

> I think you're
> thinking of the tricky counter idiom, which is relatively little
> used today.

OK, that's what the problem was: all those static objects instantiated all 
over the place incrementing/decrementing the counter. Yes, Singleton 
techniques do not inherently have that problem.

> Order of initialization can be a serious problem, however, and
> one of the main reasons I sometimes use C style arrays instead
> of std::vector is precisely to obtain static initialization, and
> avoid order of initialization problems.  (Similarly, I'll use a
> presorted C style array and std::lower_bound rather than
> std::map or std::set for constant objects with static lifetime,
> in order to avoid order of initialization problems.)

John 


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

0
JohnQ
2/16/2007 3:32:19 PM
"James Kanze" <james.kanze@gmail.com> wrote in message 
news:1171619989.995661.215400@q2g2000cwa.googlegroups.com...
> JohnQ wrote:

>> OK, good explanation. I get it. I was wondering overall if
>> there was such an animal as static initialization of class
>> object instances at "global" (namespace) scope.
>
> Sure:
>
>    struct Toto
>    {
>        int a ;
>        int b ;
>    } ;
>
>    Toto x = { -1, 42 } ;
>
> Static initialization of an object with class type at namespace
> scope.  The critical part related to the type is that the object
> must be a POD; POD structs (which have class type) can be
> initialized statically, just like any other POD.
>
> Note that anything which prevents POD-ness prevents static
> initialization.  Any user defined constructor, obviously, but
> also any private or protected non-static data members, any
> virtual functions, any base classes, a user defined assignment
> operator or a user defined destructor.

OK, I was using "class object instances" as "non-POD".

John 


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

0
JohnQ
2/16/2007 3:32:56 PM
Maciej Sobczak wrote:
> JohnQ wrote:

> > I'm still quite confused about "static
> > storage duration" vs. "class objects declared with the static keyword" vs.
> > "static vs. dynamic initialization". For instance, is a constructor
> > initialization list part of "dynamic initialization"?

> Yes. The initialization list in its entirety is not a constant
> expression (even if each component in the list if initialized by
> constant expression) and as such is not performed statically.

An initialization list can certainly contain constant
expressions.  But (and I think that's what you are trying to
say) an initialization list is part of a user defined
constructor; if the object has a user defined constructor, it
cannot be statically initialized.

> If the given object has static storage duration, its constructor is
> literally executed, and is not magically "given" by the
> compiler/linker/loader/etc.

Except that a few optimizations are permitted.

> Now, *when* this constructor is executed
> depends on how the object was declard - if it's a static local object
> inside some function, then it's constructed the first time its
> declaration is encountered; and some time before the first explicit
> statement in function main otherwise.

Again, the standard doesn't guarantee before main, even if it's
true that you can pretty well count on it for statically linked
components.  (Dynamic linking introduces a whole other bag of
issues.)

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



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

0
James
2/17/2007 10:38:00 AM
On Feb 16, 2:57 pm, "James Kanze" <james.ka...@gmail.com> wrote:
> Order of initialization can be a serious problem, however, and
> one of the main reasons I sometimes use C style arrays instead
> of std::vector is precisely to obtain static initialization, and
> avoid order of initialization problems.  (Similarly, I'll use a
> presorted C style array and std::lower_bound rather than
> std::map or std::set for constant objects with static lifetime,
> in order to avoid order of initialization problems.)

That's an interesting idea, but in some exotic cases you still have
potential destruction ordering problems. Alexandrescu addresses this
in his "Modern C++ Design" using the term "phoenixing singleton".

----- stephan


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

0
s5n
2/17/2007 10:45:26 AM
s5n wrote:
> On Feb 16, 2:57 pm, "James Kanze" <james.ka...@gmail.com> wrote:
> > Order of initialization can be a serious problem, however, and
> > one of the main reasons I sometimes use C style arrays instead
> > of std::vector is precisely to obtain static initialization, and
> > avoid order of initialization problems.  (Similarly, I'll use a
> > presorted C style array and std::lower_bound rather than
> > std::map or std::set for constant objects with static lifetime,
> > in order to avoid order of initialization problems.)

> That's an interesting idea, but in some exotic cases you still have
> potential destruction ordering problems.

Such as?  If I'm using PODs, there is no destruction.  For that
matter, when using the singleton pattern, I normally don't
destruct the objects.  It's not necessary, and it is dangerous.

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



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

0
James
2/17/2007 6:56:46 PM
On Feb 15, 3:49 am, Maciej Sobczak <no.s...@no.spam.com> wrote:
> Note also that static initialization is not necessarily compile-time.
> Consider a big global array:
>
> int bigArray[10000000];
>
> On the machine where int is 32 bits initializing this array at compile
> time would require putting some 40MB of zeros in the executable, which
> would be just wasteful. Today linkers don't do this and instead the
> array is created and cleared at the time the program is loaded into
> memory. This is no longer compile-time, but still before any dynamic
> initialization, as the standard requires.

Following on this, can someone confirm that for a local array that is
0 initialized machine instructions at run time will not be used to
initialize the array?

void foo()
{
  char buffer[1024] =  {};
}

Often times I have seen code that uses memset to initialize this kind
of local array to 0's but presumably using an initialization like
above is faster.

Thank you,

Ivan Novick
http://www.0x4849.net


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

0
Ivan
2/20/2007 6:49:49 AM
Ivan Novick wrote:

> Following on this, can someone confirm that for a local array that is
> 0 initialized machine instructions at run time will not be used to
> initialize the array?

If the object is not statically initialized, then some runtime effort 
will be necessary to initialize it at... runtime.

> void foo()
> {
>   char buffer[1024] =  {};
> }

For example, above. The buffer array is not statically initialized 
(moreover, it's initialized every time foo is executed).

> Often times I have seen code that uses memset to initialize this kind
> of local array to 0's but presumably using an initialization like
> above is faster.

No, there is not provision that the above will be faster than memset. It 
is certainly more readable and robust, but nothing can be said about 
performance until you measure it.

Note also that an alternative for memset is std::fill, which in some 
cases *might* be faster than memset, although I would not expect this 
for the above char array.


-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/

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

0
Maciej
2/20/2007 8:55:13 AM
On Feb 20, 1:49 pm, "Ivan Novick" <ivan.d.nov...@gmail.com> wrote:
> On Feb 15, 3:49 am, Maciej Sobczak <no.s...@no.spam.com> wrote:

> > Note also that static initialization is not necessarily compile-time.
> > Consider a big global array:

> > int bigArray[10000000];

> > On the machine where int is 32 bits initializing this array at compile
> > time would require putting some 40MB of zeros in the executable, which
> > would be just wasteful. Today linkers don't do this and instead the
> > array is created and cleared at the time the program is loaded into
> > memory. This is no longer compile-time, but still before any dynamic
> > initialization, as the standard requires.

> Following on this, can someone confirm that for a local array that is
> 0 initialized machine instructions at run time will not be used to
> initialize the array?

You never have a guarantee concerning how many instructions are
used to do what.  Even with static initialization; the OS must
execute some instructions to load the values from disk, zap
otherwise uninitized memory, etc.

> void foo()
> {
>   char buffer[1024] =  {};
>
> }

This is dynamic initialization.  In all implementations that I
know, memory for it isn't allocated until the function is
called.  (Other solutions are possible, but tricky, because
foo() can be called recursively.)

> Often times I have seen code that uses memset to initialize this kind
> of local array to 0's but presumably using an initialization like
> above is faster.

Presumably.  The compiler has more information that memset, and
should be able to generate faster code, or at least as fast.
(If it can't generate faster code, it can generate a call to
memset.  But the last time I saw a case where it couldn't
generate faster code was for an 8080.)

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



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

0
James
2/21/2007 6:17:10 AM
Maciej Sobczak wrote:
> Ivan Novick wrote:

> > Following on this, can someone confirm that for a local array that is
> > 0 initialized machine instructions at run time will not be used to
> > initialize the array?

> If the object is not statically initialized, then some runtime effort
> will be necessary to initialize it at... runtime.
>
> > void foo()
> > {
> >   char buffer[1024] =  {};
> > }

> For example, above. The buffer array is not statically initialized
> (moreover, it's initialized every time foo is executed).

> > Often times I have seen code that uses memset to initialize this kind
> > of local array to 0's but presumably using an initialization like
> > above is faster.

> No, there is not provision that the above will be faster than memset. It
> is certainly more readable and robust, but nothing can be said about
> performance until you measure it.

How true.

> Note also that an alternative for memset is std::fill, which in some
> cases *might* be faster than memset, although I would not expect this
> for the above char array.

Not to mention uninitialized_fill, and their _n variants.

A quick glance at the assembler on Sparc, with both g++ and Sun
CC, rather disappointed me.  In none of the cases did the
compiler seem to take advantage of the fact that it knew that
the data was aligned, and that the size was a multiple of the
word size, nor did either compiler have any "built-in" memset
(which IIRC was almost standard for C compilers, 20 years ago).
Both compilers treated an explicit call to memset as if it were
an external and unknown function; g++ generated a call to memset
for the above, and in all other cases (the C++ template
functions being inline), the compilers generated a loop storing
bytes.  (Since the data is in fact aligned, and the number of
bytes is a multiple of the word size, looping 256 times, storing
words, is an obvious optimization.  Back when I was working on
the standard library for a C compiler, doing this in the
implementation of memset was standard procedure.  But of course,
within memset, this meant dynamic checks.)

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



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

0
James
2/21/2007 6:17:27 AM
In article <1172052568.002621.320240@v45g2000cwv.googlegroups.com>,
james.kanze@gmail.com says...

[ ... ]

> A quick glance at the assembler on Sparc, with both g++ and Sun
> CC, rather disappointed me.  In none of the cases did the
> compiler seem to take advantage of the fact that it knew that
> the data was aligned, and that the size was a multiple of the
> word size, nor did either compiler have any "built-in" memset
> (which IIRC was almost standard for C compilers, 20 years ago).
> Both compilers treated an explicit call to memset as if it were
> an external and unknown function; g++ generated a call to memset
> for the above, and in all other cases (the C++ template
> functions being inline), the compilers generated a loop storing
> bytes.  (Since the data is in fact aligned, and the number of
> bytes is a multiple of the word size, looping 256 times, storing
> words, is an obvious optimization.  Back when I was working on
> the standard library for a C compiler, doing this in the
> implementation of memset was standard procedure.  But of course,
> within memset, this meant dynamic checks.)

At one time, tricks like these made a huge difference in effective
speed. Now, except under quite limited circumstances, they don't. On a
modern processor, the instruction sequence you use to fill memory has
little real effect on the speed at which the memory is actually filled.

On a typical modern machine, the processor runs a LOT faster than the
memory. _If_ the data you're writing is already in the cache, the
instruction sequence can make a real difference in execution speed.
Otherwise, it'll typically be limited by the bandwidth to memory, and
instruction sequences that write a byte at a time will be within a few
percent of sequences that write a 64-bit word at a time.

The extra instructions necessary to write any mis-aligned bytes at the
beginning, then the aligned middle section, then any misaligned data at
the end rarely accomplishes much anymore.

Of course, if you look at things like DSPs the picture changes -- DSPs
tend to work with large data streams, so they have lots of memory
bandwidth instead of small, fast caches. Many of them, however, have
special data transfer units to handle things like large memory fills
and/or moves.

--
    Later,
    Jerry.

The universe is a figment of its own imagination.

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

0
Jerry
2/24/2007 4:54:45 AM
Reply: