Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Alignment of foo[1][1][1][1]

Reply
Thread Tools

Alignment of foo[1][1][1][1]

 
 
Shao Miller
Guest
Posts: n/a
 
      06-30-2011
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? If I do:

typedef foo bar[1][1][1][1];
bar * my_bar = malloc(sizeof *bar);
foo * my_foo = (foo *) my_bar;

certainly 'my_bar' points to an object whose alignment satisfies type
'foo'. But what about the other way around?

typedef foo bar[1][1][1][1];
foo * my_foo = malloc(sizeof *foo);
bar * my_bar = (bar *) my_foo;

'my_foo' could point to an object aligned for '2', but if the alignment
requirement for 'bar' is '4', then the behaviour is undefined.

With a size of '16', array elements would always satisfy both alignment
requirements.

My guess is that no implementation does this, but again: How about
Standard-wise?
 
Reply With Quote
 
 
 
 
Shao Miller
Guest
Posts: n/a
 
      06-30-2011
On 6/29/2011 11:11 PM, Shao Miller 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? If I do:
>
> typedef foo bar[1][1][1][1];
> bar * my_bar = malloc(sizeof *bar);
> foo * my_foo = (foo *) my_bar;
>
> certainly 'my_bar' points to an object whose alignment satisfies type
> 'foo'. But what about the other way around?
>
> typedef foo bar[1][1][1][1];
> foo * my_foo = malloc(sizeof *foo);
> bar * my_bar = (bar *) my_foo;
>
> 'my_foo' could point to an object aligned for '2', but if the alignment
> requirement for 'bar' is '4', then the behaviour is undefined.
>
> With a size of '16', array elements would always satisfy both alignment
> requirements.
>
> My guess is that no implementation does this, but again: How about
> Standard-wise?


Erm, pretend I didn't use 'malloc', there. That's besides the point.
 
Reply With Quote
 
 
 
 
Harald van Dijk
Guest
Posts: n/a
 
      07-01-2011
On Jun 30, 5:11*am, Shao Miller <(E-Mail Removed)> wrote:
> My guess is that no implementation does this,


Perhaps not for arrays of length 1, but it could be a sensible
decision to require the same alignment as an int for
char[sizeof(int)]. And on my system, the natural alignment for long
long is 8 bytes, but the compiler aligns them to 4 bytes mainly to
avoid changing the ABI. It could be a sensible future decision to keep
that alignment for long long, but align arrays of long long to 8
bytes, if the cost of the ABI change would be acceptably small for
arrays. (Not that I think that is going to happen, but still...)

> but again: How about
> Standard-wise?


I don't think the standard says anything about it, which in this case
means implementors are given the freedom to use whatever alignment
works best for them.
 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      07-02-2011
Shao Miller <(E-Mail Removed)> 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. 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?
--
Larry Jones

The authorities are trying to silence any view contrary to their own!
-- Calvin
 
Reply With Quote
 
Harald van Dijk
Guest
Posts: n/a
 
      07-02-2011
On Jul 2, 7:56*pm, (E-Mail Removed) wrote:
> 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.


In n1256, the only relevant wording regarding treating arbitrary
objects as arrays that I can find is this:

"For the purposes of these operators, a pointer to an object that is
not an element of an
array behaves the same as a pointer to the first element of an array
of length one with the
type of the object as its element type." (for the + - < <= > >= ==
and != operators)

which does not suggest to me that objects behave as arrays of length 1
in other aspects. Am I overlooking something?
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-03-2011
Shao Miller <(E-Mail Removed)> writes:

> 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? [snip]


No, it's conforming. An array must be aligned at least as
strictly as its elements, but the converse doesn't hold,
even for arrays of length 1. The alignments for types (foo)
and (foo[1]) don't have to be the same, even though in any
sane implementation they will be.
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-03-2011
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> Shao Miller <(E-Mail Removed)> 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.)

 
Reply With Quote
 
lawrence.jones@siemens.com
Guest
Posts: n/a
 
      07-06-2011
Tim Rentsch <(E-Mail Removed)> wrote:
> (E-Mail Removed) writes:
> > 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.


No, I meant exactly what I said. You're either missing the distinction
I was trying to draw between the necessary and preferred alignments or
you're conflating them.

> 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[*].


But a pointer to an array must compare equal to a pointer to the first
element (when converted to a common type, of course), which isn't
possible in general unless the necessary alignments are the same. The
preferred alighments can differ as you said above.
--
Larry Jones

These findings suggest a logical course of action. -- Calvin
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      07-06-2011
On 7/2/2011 17:16, Harald van Dijk wrote:
> On Jul 2, 7:56 pm, (E-Mail Removed) wrote:
>> 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.

>
> In n1256, the only relevant wording regarding treating arbitrary
> objects as arrays that I can find is this:
>
> "For the purposes of these operators, a pointer to an object that is
> not an element of an
> array behaves the same as a pointer to the first element of an array
> of length one with the
> type of the object as its element type." (for the + -< <=> >= ==
> and != operators)
>
> which does not suggest to me that objects behave as arrays of length 1
> in other aspects. Am I overlooking something?


Do you mean such as the cast concern of the original post? That seems
like a slippery slope. :S
 
Reply With Quote
 
Harald van Dijk
Guest
Posts: n/a
 
      07-06-2011
On Jul 6, 3:07*pm, Shao Miller <(E-Mail Removed)> wrote:
> On 7/2/2011 17:16, Harald van Dijk wrote:
> > On Jul 2, 7:56 pm, (E-Mail Removed) wrote:
> >> 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 arraycannot
> >> be stricter than the necessary alignment of its element type.

>
> > In n1256, the only relevant wording regarding treating arbitrary
> > objects as arrays that I can find is this:

>
> > "For the purposes of these operators, a pointer to an object that is
> > not an element of an
> > * array behaves the same as a pointer to the first element of an array
> > of length one with the
> > * type of the object as its element type." (for the + -< *<=> *>= ==
> > and != operators)

>
> > which does not suggest to me that objects behave as arrays of length 1
> > in other aspects. Am I overlooking something?

>
> Do you mean such as the cast concern of the original post? *That seems
> like a slippery slope. :S


In what way? I don't see any downsides to disallowing

int i = 0;
++(*(int(*)[1])&i)[0];

If you need an array, do this:

int i[1] = { 0 };
++i[0];

If you don't need an array, do this:

int i = 0;
++i;

Do you have a real example where it would be useful for you to
reinterpret a non-array as an array (beyond what the standard already
permits)?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Regd---Justify option in Alignment. =?Utf-8?B?bWFudQ==?= ASP .Net 0 09-23-2005 07:35 AM
Phase alignment ALuPin VHDL 0 05-17-2004 09:12 AM
Closing a browser, crystal report viewer alignment Anne ASP .Net 0 07-30-2003 02:49 PM
Crystal Reports Viewer alignment Anne ASP .Net 0 07-29-2003 03:34 PM
Re: Help required for alignment problem Sunil Menon ASP .Net 0 06-26-2003 07:56 AM



Advertisments