Tim Rentsch
7/3/2011 10:57:00 PM
lawrence.jones@siemens.com writes:
> Shao Miller <sha0.miller@gmail.com> wrote:
>> Suppose I have type 'foo' and:
>>
>> sizeof (foo) == 16
>> alignof (foo) == 2
>>
>> Suppose I have type 'foo[1][1][1][1]' and:
>>
>> sizeof (foo[1][1][1][1]) == 16
>>
>> Can:
>>
>> alignof (foo[1][1][1][1]) == 4
>>
>> ? I'd like to think not, but is it prohibited?
>
> I'm afraid it's hard to say. The problem is that there are at least two
> potentially different kinds of alignment requirements, which I'll call
> the *necessary* alignment and the *preferred* alignment. The necessary
> alignment is the alignment required by the underlying hardware and the
> implementation's code generation in order for things to work correctly.
> The preferred alignment may be stricter and is what the implementation
> actually uses, typically for performance reasons. For example, on a
> typical linearly addressed machine that allows unaligned accesses, the
> necessary alignment for all types is 1, but implementations almost
> always use an alignment equal to the size for the fundamental data
> types.
>
> The C Standard requires that any object be usable as if it were an array
> with a single element. Thus, the necessary alignment of an array cannot
> be stricter than the necessary alignment of its element type.
You mean this the other way around - the alignment of an array
type must be at least as strict as the element type, and may
in fact be more strict. The requirement you mention is in
reference to element and array objects, not types; it doesn't
bear on the issue of alignment of array types, because the
pointers involved always point to an element of the array in
question, ie, they are of element type, not array type [*].
[*] With the understanding that the element type may itself be
a (different) array type, but that doesn't change the point.
> However,
> there certainly are implementations that align arrays more strictly than
> their element type for performance reasons, and I wouldn't be surprised
> to find some that do the same for structure types (although I've never
> encountered one).
>
> The Standard says that _Alignof() returns the "required" alignment, but
> it's not clear exactly what "required" means in this context. Is it the
> necessary alignment, the preferred alignment, or maybe even something in
> between?
Surely the meaning of _Alignof() is meant to coincide with what
is necessary for conversion of a pointer to the type in question.
So for example,
char *stuff = malloc( _Alignof (T) + sizeof (T) );
... verify the malloc succeeded ...
T *displaced = (T*) (stuff + _Alignof (T));
must work on a conforming implementation. It's also possible
some lesser values would work, but _Alignof (T) must be
/guaranteed/ to work, since otherwise having _Alignof would be of
no value.
(I think it goes without saying that _Alignof also must be such
that the alignments of members if T is a struct or union type, or
elements if T is an array type, will each have their individual
requirements satisfied -- meaning they can be accessed normally
and their addresses will work when converted to their respective
types. The alignment of a struct type must take into account the
alignments of its members, etc.)