text,data and bss

H

Harald van Dijk

Harald said:
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.

In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

No, it's not, and in the general case, it can't be:

union {
char x[sizeof(double) - 1];
double d;
} u = { 0 };

There isn't any way to zero-initialise the final byte of d. (I'm assuming
sizeof(double) is not 1.)
This example could be inefficient if all-bits-zero wasn't 0.0, forcing
the entire union into .data instead of .bss, but I don't think you'd get
"random bytes" in the non-overlapping part of u.x.

If real-world compilers don't clear out bits in floating point constants
that don't contribute to the value (admittedly, this is not by a
conforming compiler, but it's not one of the areas in which it doesn't
conform), it wouldn't surprise me if real-world compilers don't clear out
bytes in unions that don't contribute to the value.
 
J

James Harris

Harald said:
Harald van D©¦k wrote:
On Sun, 16 Nov 2008 22:27:37 +0000, Richard Tobin wrote:
If 0.0 is all zeros, then a zero-initialised section can be used for
it.
If it's not, then you need something like .data that can be
initialised
to any value. Neither case suggests a .bss that is not initialised at
all.
Oh, sure, initialised to whatever random bytes the compiler happened to
have in memory when laying out the .data section or equivalent is
effectively uninitialised to me.
Uh, what? If all-bits-zero (which is what you'd get in .bss) does not
mean 0.0, then the compiler would instead create an entry in .data that
_does_ mean 0.0. There is no initialization to "whatever random bytes
the compiler happened to have in memory"; either way, the variable will
end up being 0.0.

union {
double d;
char x[1000];
} u = { 0 };
u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.

In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

This example could be inefficient if all-bits-zero wasn't 0.0, forcing
the entire union into .data instead of .bss, but I don't think you'd get
"random bytes" in the non-overlapping part of u.x.

I don't think it is possible for C to initialise both components of
the above union to zero - at least not in the general case. Where the
machine has a double zero representation that is not all zero bits it
is impossible to zero both.

James
 
J

James Kuyper

jameskuyper said:
Stephen said:
Harald van D©¦k wrote: ...
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.
In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

No.

Sorry - that wasn't meant to be so abrupt - I accidentally sent that
message when I'd just barely started writing it.

6.2.6.1p6: "When a value is stored in an object of structure or union
type, including in a member object, the bytes of the object
representation that correspond to any padding bytes take
unspecified values."

6.2.6.1p7: "When a value is stored in a member of an object of union
type, the bytes of the object representation that do not correspond to
that member but do correspond to other members take unspecified values."

You're probably thinking of the following rule:

6.7.8p21: "... the remainder of the aggregate shall be initialized
implicitly the same as objects that have static storage duration."

However, unions are NOT aggregates, so this rule only applies to
structures or arrays.
 
L

lawrence.jones

Stephen Sprunk said:
Harald said:
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.

In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

Not so far, but there's a fair chance that C1X will require it.
 
K

Keith Thompson

Stephen Sprunk said:
Harald said:
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.

In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

Not so far, but there's a fair chance that C1X will require it.

Really? How will something like this be handled?

union {
int i;
double d;
};

Suppose sizeof(double) > sizeof(int), and double(0.0) isn't
represented as all-bits-zero.

Or consider:

union {
int i;
float f;
void *p;
}

Which member gets zeroed? Will this apply only to non-overlapping
members? (Obviously all top-level members overlap; this can apply
only to submembers.)
 
S

Stephen Sprunk

Keith said:
Stephen Sprunk said:
Harald van D??k wrote:
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the bytes that
follow u.d.

In that example, isn't the part of u.x not overlapping with u.d supposed
to be zero-filled as well?

Not so far, but there's a fair chance that C1X will require it.

Really? How will something like this be handled?

union {
int i;
double d;
};

Suppose sizeof(double) > sizeof(int), and double(0.0) isn't
represented as all-bits-zero.

If you are initializing d, nothing would change since there is no
non-overlapping part of i.

In the case where sizeof(int) > sizeof(double), then the non-overlapping
bytes in i would be zero-filled. That is, in fact, what happens with
every implementation I've used (since they zero-fill all memory before
giving it to a process), which is part of why I had thought it was
required. (The is that I rarely use unions, so I keep thinking of the
rules for structs, which are similar but not identical.)
Or consider:

union {
int i;
float f;
void *p;
}

Which member gets zeroed? Will this apply only to non-overlapping
members? (Obviously all top-level members overlap; this can apply
only to submembers.)

See above. The proposed change would only affect the non-overlapping
parts of members that weren't explicitly initialized.

S
 
K

Keith Thompson

Stephen Sprunk said:
Keith said:
Harald van D??k wrote:
Given

union {
double d;
char x[1000];
} u = { 0 };

u.d will be initialised to zero, but I was talking about the
bytes that follow u.d.

In that example, isn't the part of u.x not overlapping with u.d
supposed to be zero-filled as well?

Not so far, but there's a fair chance that C1X will require it.
Really? How will something like this be handled?
union {
int i;
double d;
};
Suppose sizeof(double) > sizeof(int), and double(0.0) isn't
represented as all-bits-zero.

If you are initializing d, nothing would change since there is no
non-overlapping part of i.

In the case where sizeof(int) > sizeof(double), then the
non-overlapping bytes in i would be zero-filled. That is, in fact,
what happens with every implementation I've used (since they zero-fill
all memory before giving it to a process), which is part of why I had
thought it was required. (The is that I rarely use unions, so I keep
thinking of the rules for structs, which are similar but not
identical.)
Or consider:
union {
int i;
float f;
void *p;
}
Which member gets zeroed? Will this apply only to non-overlapping
members? (Obviously all top-level members overlap; this can apply
only to submembers.)

See above. The proposed change would only affect the non-overlapping
parts of members that weren't explicitly initialized.

Given:

static union {
int i;
void *p[100];
} obj;

C99 currently states that i is initialized to 0, and the initial value
of p isn't specified. So with the proposed change, all bytes of obj.p
beyond the first sizeof(int) bytes will be set to 0, even if
all-bits-zero isn't a representation of a null pointer?

How is that useful?
 
L

lawrence.jones

Keith Thompson said:
Really? How will something like this be handled?

union {
int i;
double d;
};

Suppose sizeof(double) > sizeof(int), and double(0.0) isn't
represented as all-bits-zero.

The proposal is that the "extra" bytes be initialized to zero (actually,
it says that *all* the bytes are set to zero before the regular
initialization process occurs). How useful that is depends on the
actual types involved and their representations, but it reflects
existing practice on the vast majority of implementations.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top