468,790 Members | 1,941 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,790 developers. It's quick & easy.

About initializing non-local object

Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."

Does this mean all non-local objects will be zero-initialized before
they are initialized by their initializers(if they have)? For example:

int g_var = 3;
int main() {}

Will g_var be first initialized to zero, then to 3?
Jun 27 '08 #1
13 1984
On May 14, 8:20*pm, WaterWalk <toolmas...@163.comwrote:
Hello. When I consult the ISO C++ *standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."

Does this mean all non-local objects will be zero-initialized before
they are initialized by their initializers(if they have)? For example:

int g_var = 3;
int main() {}

Will g_var be first initialized to zero, then to 3?
Yes. Or more accurately, if a program were to observe g_var's value
that is the initialization sequence of g_var's value - that that
program would see.

Greg

Jun 27 '08 #2
WaterWalk wrote:
Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."
Is that a draft? Mine says:

"The storage for objects with static storage duration shall be
zero-initialized before any other initialization takes place."

This sounds more logical, since in C++, an object can by definition be
initialized only once.
Does this mean all non-local objects will be zero-initialized before
they are initialized by their initializers(if they have)?
I guess it does - more or less. See below.
For example:

int g_var = 3;
int main() {}

Will g_var be first initialized to zero, then to 3?
Well, you won't notice any difference, since it will be initialized to 3
before you can access it for the first time. In such a case, the "as-if"
rule can be used, that says that the program doesn't need to do exactly as
the standard says. It just has to have the same observable effect as a
program that would. Since there is no standard-compliant way to observe
that the object's storage is initialized to zero before the object's real
initialization, compilers are free to not do that.
This is more relevant for objects that get initialized dynamically (i.e.
classes with constructors).

Jun 27 '08 #3
On May 15, 12:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
WaterWalk wrote:
Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."

Is that a draft? Mine says:

"The storage for objects with static storage duration shall be
zero-initialized before any other initialization takes place."

This sounds more logical, since in C++, an object can by definition be
initialized only once
Mine is the 2003 version. Maybe yours is the 1998 version.
Jun 27 '08 #4
On May 15, 6:22 am, Greg Herlihy <gre...@mac.comwrote:
On May 14, 8:20 pm, WaterWalk <toolmas...@163.comwrote:
When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states: "Objects with static
storage duration shall be zero-initialized before any other
initialization takes place."
Does this mean all non-local objects will be
zero-initialized before they are initialized by their
initializers(if they have)? For example:
int g_var = 3;
int main() {}
Will g_var be first initialized to zero, then to 3?
Yes. Or more accurately, if a program were to observe g_var's
value that is the initialization sequence of g_var's value -
that that program would see.
In theory. If the initialization is static (as it is here),
then there is no way a program can see the zero initialization
(and I know of no implementation which actually does it). If
the initialization isn't static, of course, then it does matter.
E.g.

extern int f() ;
extern int g() ;

int i = f() ;
int j = g() ;
int f()
{
return j ;
}

int g()
{
return 3 ;
}

This is guaranteed to initialize i to 0, and j to 3.

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #5
WaterWalk wrote:
On May 15, 12:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
>WaterWalk wrote:
Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."

Is that a draft? Mine says:

"The storage for objects with static storage duration shall be
zero-initialized before any other initialization takes place."

This sounds more logical, since in C++, an object can by definition be
initialized only once

Mine is the 2003 version. Maybe yours is the 1998 version.
Yes, it is. But then I can just wonder why they changed that part of the
text.

Jun 27 '08 #6
On May 15, 9:36 pm, Rolf Magnus <ramag...@t-online.dewrote:
WaterWalk wrote:
On May 15, 12:19 pm, Rolf Magnus <ramag...@t-online.dewrote:
WaterWalk wrote:
Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."
Is that a draft? Mine says:
"The storage for objects with static storage duration shall be
zero-initialized before any other initialization takes place."
This sounds more logical, since in C++, an object can by definition be
initialized only once
Mine is the 2003 version. Maybe yours is the 1998 version.
Yes, it is. But then I can just wonder why they changed that
part of the text.
Maybe because it doesn't say what was meant. What does
zero-initializing the storage for an object mean, for that
matter? Storage is raw memory, at best, an array of unsigned
char. And initializing the underlying storage with all 0 bits
is definitly NOT what was meant (and would be incompatible with
C). The standard defines clearly what zero-initialization of an
object means (and it's clear that the object isn't "initialized"
in the classical sense after it, nor does the object "exist" as
such after such initialization, at least not if it isn't a POD).

--
James Kanze (GABI Software) email:ja*********@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

Jun 27 '08 #7
James Kanze wrote:
Mine is the 2003 version. Maybe yours is the 1998 version.

Yes, it is. But then I can just wonder why they changed that
>part of the text.

Maybe because it doesn't say what was meant. What does
zero-initializing the storage for an object mean, for that
matter?
Well, I read it up in the 98 standard, and it doesn't mean what I expected
it to. It doesn't seem to be defined for the storage for non-PODs at all,
only for PODs. What the standard calls "zero initializing the storage for
an object", I would have called "zero initializing an object", separating
storage (raw memory, for which "zero initializing" means setting all bits
to 0), and objects (for which "zero initializing" means giving it the
type's representation of the zero value).
Storage is raw memory, at best, an array of unsigned
char. And initializing the underlying storage with all 0 bits
is definitly NOT what was meant
That's what I would have expected though. But if that wasn't meant, what
was?
(and would be incompatible with C).
In which way?
The standard defines clearly what zero-initialization of an
object means (and it's clear that the object isn't "initialized"
in the classical sense after it, nor does the object "exist" as
such after such initialization, at least not if it isn't a POD).
I just find it stange that the object is said to be initialzed twice.
Jun 27 '08 #8
WaterWalk wrote:

>That's not really true. Zero initialization doesn't affect
references, for example (which can't be zero initialized), and
doesn't do the right thing for objects with non-trivial
initializers. (Calling a virtual function on an object whose
vptr is null is not going to do anything good.)

I never thought an object's vptr might be zero even after zero
initialization.
What would you expect it to be?

Jun 27 '08 #9
On 16 mai, 23:51, Rolf Magnus <ramag...@t-online.dewrote:
James Kanze wrote:
Mine is the 2003 version. Maybe yours is the 1998 version.
Yes, it is. But then I can just wonder why they changed that
part of the text.
Maybe because it doesn't say what was meant. What does
zero-initializing the storage for an object mean, for that
matter?
Well, I read it up in the 98 standard, and it doesn't mean
what I expected it to. It doesn't seem to be defined for the
storage for non-PODs at all, only for PODs. What the standard
calls "zero initializing the storage for an object", I would
have called "zero initializing an object", separating storage
(raw memory, for which "zero initializing" means setting all
bits to 0), and objects (for which "zero initializing" means
giving it the type's representation of the zero value).
Apparently, the text in C++98 didn't satisfy the committee,
either, since it got reworked in C++03. The basic idea was,
however, for an object with dynamic initialization to be
initialized as if it had no explicit initializer in C. Thus,
pointers are null, int's 0, doubles 0.0, etc. It's somewhat
difficult to formulate, however, because C++ has other types of
objects as well.
Storage is raw memory, at best, an array of unsigned char.
And initializing the underlying storage with all 0 bits is
definitly NOT what was meant
That's what I would have expected though. But if that wasn't
meant, what was?
More or less:

in a composite object (class or array), each of the
component parts is zero initialized, recursively, until you
reach a non-composite object,

for unions, the first member is zero initialized,

for pointers (including pointers to members) and arithmetic
types, zero initialization is the equivalent of initializing
with a 0, converted to the appropriate type, and

for references and internal data, nothing (you can't
initialize a reference with 0, and you can't legally do
anything which would require internal data, like the vptr,
until dynamic initialization runs).
(and would be incompatible with C).
In which way?
Except for the bit about references, the rules above are those
of C. In particular, pointers are initialized with a null
pointer (not with all bits 0), and floating point with 0.0
(which formally may not have all bits 0, although I've never
heard of a case where it was otherwise). And in something like:

union { char* a; char b[10000] ; } ;

only the element a is initialized (as a null pointer, which
might mean that b[0] != 0).
The standard defines clearly what zero-initialization of an
object means (and it's clear that the object isn't "initialized"
in the classical sense after it, nor does the object "exist" as
such after such initialization, at least not if it isn't a POD).
I just find it strange that the object is said to be
initialzed twice.
It is. But it's a very special kind of initialization. And
since it definitly takes type information into account, I don't
know what else you'd call it.

--
James Kanze (GABI Software) email:ja*********@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
Jun 27 '08 #10
On May 17, 5:52 am, Rolf Magnus <ramag...@t-online.dewrote:
WaterWalk wrote:
That's not really true. Zero initialization doesn't affect
references, for example (which can't be zero initialized), and
doesn't do the right thing for objects with non-trivial
initializers. (Calling a virtual function on an object whose
vptr is null is not going to do anything good.)
I never thought an object's vptr might be zero even after zero
initialization.

What would you expect it to be?
I thought the object is initialized "normally" with that all members
zero. Thus it can be used like a normal object(calling member
functions, etc). But according to James Kanze, after zero-
initialization, an object(its vptr for example) may not be set up
properly.
Jun 27 '08 #11
>>
>class A {
public:
A(const A& a, const std::string& name) { cout << name << endl; }

};

file 1:
-------
extern A a2;
A a1(a2, "a1");

file 2:
-------
extern A a1;
A a2(a1, "a2");

And got no compilation error. In this case, what is the behaviour ? is
it well defined ?

Thanks.

It seems this should be discussed in two aspects:
1) If a1 and a2 are initialized before main, then when their
constructors are called, both are already zero-initialized. Since the
above code doesn't use the contents of a1 and a2, I don't think there
is any problem.
I just wanted to spot this. Put some use of the the 'a' parameter in the
ctor body if you want: the content of a1 and a2 will be used.
>
2) If a1 and a2 are initialized after main, their initializations
shall occur before their first uses. And according to the standard,
such an initialization shall take place before the object's first use
of any function or object defined in the same translation unit, the
calling of A's constructor looks like a indefinite recursive loop:
before call a2's constructor, a1 shall be initialized first. But to
initialize a1, a2's constructor shall be first called. And so on.
Well, I tend to be agreed with, the compiler should get into generating
a recursive initialization. a1 needs a2 so let's generate a2 ctor call
first; to do that i need to generate call for a1 ctor first, etc...
Jun 27 '08 #12
WaterWalk wrote:
On May 17, 5:52 am, Rolf Magnus <ramag...@t-online.dewrote:
>WaterWalk wrote:
>That's not really true. Zero initialization doesn't affect
references, for example (which can't be zero initialized), and
doesn't do the right thing for objects with non-trivial
initializers. (Calling a virtual function on an object whose
vptr is null is not going to do anything good.)
I never thought an object's vptr might be zero even after zero
initialization.

What would you expect it to be?

I thought the object is initialized "normally" with that all members
zero.
What does "zero" mean for a non-pod?
Thus it can be used like a normal object(calling member
functions, etc).
You probably can't do that anyway. Think e.g. what happens if you write to
an std::string member before it got properly initialzied? You don't even
know what happens then. It might well lead to a derefrenced null pointer as
an example.

Jun 27 '08 #13
"Rolf Magnus" <ra******@t-online.dewrote in message
news:g0*************@news.t-online.com...
>Hello. When I consult the ISO C++ standard, I notice that in
paragraph 3.6.2.1, the standard states:
"Objects with static storage duration shall be zero-initialized before
any other initialization takes place."
>>Is that a draft? Mine says:
>>"The storage for objects with static storage duration shall be
zero-initialized before any other initialization takes place."
>>This sounds more logical, since in C++, an object can by definition be
initialized only once
>Mine is the 2003 version. Maybe yours is the 1998 version.
Yes, it is. But then I can just wonder why they changed that part of the
text.
I proposed the change, and I did so in part because I don't know what it
means to initialize an object's storage. Does it mean the same as using
memset to set the bytes that constitute the object's raw memory to zero? If
so, what if you're on a machine on which initializing an object that way
sets it to a value other than zero?

One of the changes between the 1998 and 2003 versions of the standard was to
clean up how initialization works. For example:

struct X {
int a;
std::string b;
};

struct Y {
int a;
int b;
};

In the 1998 standard, X().a is undefined; in the 2003 standard, it is
zero--even though Y().a is zero in both versions of the standard.
Jun 27 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

13 posts views Thread by simondex | last post: by
2 posts views Thread by Andrew Ward | last post: by
34 posts views Thread by newsposter0123 | last post: by
6 posts views Thread by alacrite | last post: by
3 posts views Thread by Jess | last post: by
5 posts views Thread by feverzsj | last post: by
2 posts views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.