From: David Lowndes on
>Here is an example of gcc running on a Mac with an Intel/AMD processor.
>Specifically, see the -m96bit-long-double and -m128bit-long-double options:
>
>http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/i386-and-x86_002d64-Options.html

I'd verify what Igor suggests. I wouldn't expect sizeof to include the
alignment padding - so the problem you're envisaging with the padding
shouldn't exist.

Dave
From: Ulrich Eckhardt on
David Lowndes wrote:
> I wouldn't expect sizeof to include the alignment padding - so the
> problem you're envisaging with the padding shouldn't exist.

I would. Imagine this code:

T t0;
T t1[1];
T t2[2];
assert((sizeof t0) == (sizeof t1));
assert((2 * sizeof t0) == (sizeof t2));

The reported size must include the padding for alignment there.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
From: David Lowndes on
>> I wouldn't expect sizeof to include the alignment padding - so the
>> problem you're envisaging with the padding shouldn't exist.
>
>I would. Imagine this code:
>
> T t0;
> T t1[1];
> T t2[2];
> assert((sizeof t0) == (sizeof t1));
> assert((2 * sizeof t0) == (sizeof t2));
>
>The reported size must include the padding for alignment there.

You've lost me there Uli - the results of that are way I'd expect (no
padding issues). Show us a complete example that illustrates the
problem.

Dave
From: Igor Tandetnik on
Ray wrote:
> "Igor Tandetnik" wrote:
>> Assigning to one member of the union and then reading another exhibits undefined behavior.
>
> Where did you get this information? Could you please refer me to the
> appropriate section of the C standard that states this is the case?

6.7.2.1p14 The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time.

6.2.4p2 The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined.

The above should be sufficient, but, as an independent evidence of the intent:

6.5.2.3p5 One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the complete type of the union is visible.

By implication, if two members of a union are _not_ structures that share a common initial sequence, then you can't store one and then inspect the other, or the special guarantee wouldn't be needed.

> Logically, to me at least, since
> all union members start at the same address, examining the bytes of only the
> most recently written member via a character pointer should yield perfectly
> valid results, and that is what I am doing.

It would yield unspecified results:

6.2.6.1p1 The representations of all types are unspecified except as stated in this subclause.

> And even if what you state is
> true I could simply set a separate character pointer equal to the address of
> the entire union and examine the individual bytes that way, thereby not
> reading using another member.

That you can do, and you don't need a union:

long l = 1;
char* p = (char*)&l;

There's a special dispensation for this:

6.5p7 An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
....
- a character type.

6.3.2.3p7 A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type... When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

However, this doesn't give you much, in view of aforementioned 6.2.6.1p1 - in general, you have no idea what to expect when looking at individual bytes of an object.


I would concede the following: if you limit yourself to architectures with "unsurprising" representations (in particular, no padding bits as defined by 6.2.6.2p1), and the only uncertainty is whether the architecture is little- or big-endian, then you can detect this by inspecting an integer via a char* pointer as shown above. But you are relying on a lot of a-priori knowledge.

However, you seem to be specifically concerned with machines that have "surprising" representation (such as padding bits within the value). I'm not even sure such beasts exist in nature. In any case, if you are so uncertain of the details of the architecture that you need to ask the question in the first place, I don't quite see how looking at individual bytes of the representation may enlighten you.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
From: Igor Tandetnik on
Igor Tandetnik wrote:
> Ray Mitchell <RayMitchell_NOSPAM_(a)MeanOldTeacher.com> wrote:
>> Here is an example of gcc running on a Mac with an Intel/AMD
>> processor. Specifically, see the -m96bit-long-double and
>> -m128bit-long-double options:
>>
>> http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/gcc-4..0.1/gcc/i386-and-x86_002d64-Options.html
>
> Do these switches affect sizeof(long double), or just __alignof(long double) ?

Answering myself - it does look like it affects the size:

Warning: if you override the default value for your target ABI, the structures and *arrays* containing long double variables will change their size.

Emphasis mine. Since arrays can't contain padding, the only way an array may change size is when the size of the element itself changes.


If I had to guess, I'd say it's a pretty good bet that the padding goes at the end (at higher addresses).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925