Pointer to inside an array

T

Tim Rentsch

Alok Singhal said:
int a[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int (*p)[5] = (int(*)[5])(a+6);

Think again. The purpose of the cast is not to silence the warning but
to coerce the value of the expression to a compatible type and eliminate
the condition that requires a diagnostic.

The code
unsigned char *ptr = (unsigned char*)(a+6);
will produce the exact same warning without the cast yet the
initialization is perfectly well defined as written.

Thanks. This is what I was looking for. I should have read the standard
more carefully as well. So 6.3.2.3p7 (N1336) applies here:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the behavior
is undefined. Otherwise, when converted back again, the result shall
compare equal to the original pointer.

There is no guarantee that int (*)[5] is correctly aligned for int *, and
even if it is, the standard makes no guarantees about dereferencing such
a pointer.

There is no guarantee that (a+6) is correctly aligned for int (*)[5],
but if it is then since it does point to an object that is suitably
composed to be one (or two) array(s) of (int[5]), and since both the
element types are (int), dereferencing it will work fine.
 
T

Tim Rentsch

Seebs said:
The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.

The Standard seems to allow the possibility that arrays of fixed
length (and having more than one element) have different
alignment requirements than arrays with one element (or
equivalently, than arrays of unknown length). 6.2.5p13 says:

Each complex type has the same representation and alignment
requirements as an array type containing exactly two elements of
the corresponding real type; the first element is equal to the
real part, and the second element to the imaginary part, of the
complex number.

It seems strange to mention the "alignment requirements [of] an
array type containing exactly two elements" if that had to be
the same as the alignment requirement of the element type.

Why should it? Look at an example using structs...

struct int_pair_t { int a; int b; };
int a[7];
struct int_pair_t *p = (struct int_pair_t *) (a + 1);

Even if one shows that there is no padding in the struct,
there is still no guarantee that a + 1 is properly aligned
for a struct int_pair_t *.

For a struct, this might be true. For an array, it's not.
Simple question: Is there anything precluding an
implementation giving struct int_pair_t a stricter
alignment than int?

I'm not sure. I think in practice you probably can't, because you can
set up an elaborate construct involving unions which allows you to prove
that you have to be able to treat a pointer to a large enough hunk of
space which is aligned properly for an int as a pointer to the first member
of the structure.

Certainly it can. Nothing preventing all structs from being
multiples of 32 bytes in length, for example, and always aligned
on a 32 byte boundary.
But structs are not the same thing as arrays. I am pretty sure that
array-of-foo has to have the same alignment requirements as foo, because
any foo can be treated as an array of 1 foo, and you can treat any pointer
to foo as an array of foo. Basically, the wording guaranteeing that
the offset in bytes of foo[1] is precisely sizeof(foo[0]) covers it.

Any array can be treated as through an array type (T(*)[1]), but
not the other direction.

So I'm pretty sure that arrays can't have alignment requirements more
restrictive than the alignment requirements of the things they're arrays
of.

For arrays of length 1, yes; for arrays of length 2 or more,
their alignments can be more restrictive.
 
D

David Thompson

Seebs said:
The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.

The Standard seems to allow the possibility that arrays of fixed
length (and having more than one element) have different
alignment requirements than arrays with one element (or
equivalently, than arrays of unknown length). 6.2.5p13 says:
<snip>

And footnote 106 to 6.7.2.1p16 on flexible array members (of a struct)
says so explicitly (though not formally normative).

That said, I've never heard of any machine which makes them different.
I DO know of machines where at least sometimes array of T is aligned
stricter than scalar T -- but all array of given T regardless of the
bound. Does anyone know (and willing to say) an actual example?
 
T

Tim Rentsch

David Thompson said:
Seebs said:
The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.

The Standard seems to allow the possibility that arrays of fixed
length (and having more than one element) have different
alignment requirements than arrays with one element (or
equivalently, than arrays of unknown length). 6.2.5p13 says:
<snip>

And footnote 106 to 6.7.2.1p16 on flexible array members (of a struct)
says so explicitly (though not formally normative).

I scratched my head when I saw this comment, and wondered why I'd
never noticed this footnote before. As it turns out, the
footnote was there in C99 but actually ended up being taken out
as part of TC1 or TC2, and so it isn't there in either N1124 or
N1256 (N1256 being the version that I use most often, because
it's the one I have electronically indexed).

That said, I've never heard of any machine which makes them different.
I DO know of machines where at least sometimes array of T is aligned
stricter than scalar T -- but all array of given T regardless of the
bound. Does anyone know (and willing to say) an actual example?

Where it's likely to come up is in numeric (especially floating
point?) vectors of short lengths (especially powers of two) that
match some sort of SIMD capability. More specifically, some of
the more exotic GPU's (about which I know very little), might be
helped by choosing a more restrictive alignment for such vectors.
 
K

Keith Thompson

Tim Rentsch said:
David Thompson said:
The problem is whether int(*)[2] can have a stricter
alignement than int *. I think it can! I can't see anything
in the standard that says a pointer to an element of an array
of N elements will always be properly aligned for a pointer
to an array of M elements if M < N.

I am pretty sure arrays don't actually have alignment requirements,
only the objects in them.

The Standard seems to allow the possibility that arrays of fixed
length (and having more than one element) have different
alignment requirements than arrays with one element (or
equivalently, than arrays of unknown length). 6.2.5p13 says:
<snip>

And footnote 106 to 6.7.2.1p16 on flexible array members (of a struct)
says so explicitly (though not formally normative).

I scratched my head when I saw this comment, and wondered why I'd
never noticed this footnote before. As it turns out, the
footnote was there in C99 but actually ended up being taken out
as part of TC1 or TC2, and so it isn't there in either N1124 or
N1256 (N1256 being the version that I use most often, because
it's the one I have electronically indexed).
[...]

The footnote was dropped in TC2:

21. Page 103 6.7.2.1
In paragraph 16, remove footnote 106.

in response to DR #282,
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_282.htm>.
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top