printf("%p\n", (void *)0);

P

pete

Keith said:
I don't believe it's possible for a short and an array of shorts to
have different required alignments. If short is 16 bits, a compiler
might choose to use, say, 32-bit alignment for arrays of shorts, but
it still has to be able to access an array of shorts that's 16-bit
aligned. For some purposes, a single short object is equivalent to an
array of 1 short.

My argument comes from this

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
int array[2][2] = {0};
int *pointer = (int *)&array;

printf("%d\n", pointer[3]);
return 0;
}

/* END new.c */

not being OK, as has been discussed on comp.std.c before.
 
K

kuyper

pete said:
That wouldn't work.
In order to access the array of unions, as an array of shorts,
the union has to be aligned for an array of shorts,
not merely aligned for short.

On most platforms, I would expect that the alignment requirements for
an array of shorts will be identical to the alignment requirements for
a single short int. On the platforms where that isn't true, you'd have
to add a member of type "array of short" to the union, which is an
example of why it's impossible to cover all theoretical possibilities
with a finite list of types.
 
W

Wojtek Lerch

Keith Thompson said:
I don't believe it's possible for a short and an array of shorts to
have different required alignments. If short is 16 bits, a compiler
might choose to use, say, 32-bit alignment for arrays of shorts, but
it still has to be able to access an array of shorts that's 16-bit
aligned. For some purposes, a single short object is equivalent to an
array of 1 short.

But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation, require
128-bit alignment?
 
K

Keith Thompson

pete said:
Keith said:
I don't believe it's possible for a short and an array of shorts to
have different required alignments. If short is 16 bits, a compiler
might choose to use, say, 32-bit alignment for arrays of shorts, but
it still has to be able to access an array of shorts that's 16-bit
aligned. For some purposes, a single short object is equivalent to an
array of 1 short.

My argument comes from this

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
int array[2][2] = {0};
int *pointer = (int *)&array;

printf("%d\n", pointer[3]);
return 0;
}

/* END new.c */

not being OK, as has been discussed on comp.std.c before.

If that's invalid, it's not becaues of alignment, it's because the
array of int being indexed has only two elements. (I offer no opinion
on the previous argument.)
 
K

Keith Thompson

Wojtek Lerch said:
But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation, require
128-bit alignment?

If you declare an array of type short[2049], you should be able to
access elements 1..2048 as an array of type short[2048]. (I'm too
tired right now either to support this with citations from the
standard or to provide sample code.)
 
W

Wojtek Lerch

Keith Thompson said:
pete said:
int array[2][2] = {0};
int *pointer = (int *)&array;

If that's invalid, it's not becaues of alignment, it's because the
array of int being indexed has only two elements. (I offer no opinion
on the previous argument.)

Also because the standard never says anything about the result of the
conversion of a pointer to an array to a pointer to int. We all know that
the intention was that the result of a pointer conversions always points to
an object that has the same first byte (except when such an object would
violate alignment requirements), but I don't think you can find such a
general promise in the standard.
 
W

Wojtek Lerch

Keith Thompson said:
Wojtek Lerch said:
But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation,
require
128-bit alignment?

If you declare an array of type short[2049], you should be able to
access elements 1..2048 as an array of type short[2048]. (I'm too
tired right now either to support this with citations from the
standard or to provide sample code.)

You can access those elements as if they were elements of an array of 2048
shorts, simply by ignoring the fact that it's not undefined behaviour to
subtract one from &arr[1]; but I don't think you'll find a citation to
demonstrate that it's OK to convert &arr[1] to (short (*)[2048]).
 
D

Dan Pop

In said:
But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation, require
128-bit alignment?

Nope, in both cases. A compiler may choose to do so, for performance
reasons, but this is not a requirement. Arrays have the same alignment
as their element type:

- An array type describes a contiguously allocated nonempty set
of objects with a particular member object type, called
the element type.36) Array types are characterized by their
======================================
element type and by the number of elements in the array.
========================================================

No mention of any special alignment issues. Which makes sense, because,
if arr is an array of N elements, the address of its second element can
be used as the address of an array of N-1 elements (after proper
conversion).

Dan
 
D

Dan Pop

In said:
Keith Thompson said:
Wojtek Lerch said:
I don't believe it's possible for a short and an array of shorts to
have different required alignments. If short is 16 bits, a compiler
might choose to use, say, 32-bit alignment for arrays of shorts, but
it still has to be able to access an array of shorts that's 16-bit
aligned. For some purposes, a single short object is equivalent to an
array of 1 short.

But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation,
require
128-bit alignment?

If you declare an array of type short[2049], you should be able to
access elements 1..2048 as an array of type short[2048]. (I'm too
tired right now either to support this with citations from the
standard or to provide sample code.)

You can access those elements as if they were elements of an array of 2048
shorts, simply by ignoring the fact that it's not undefined behaviour to
subtract one from &arr[1]; but I don't think you'll find a citation to
demonstrate that it's OK to convert &arr[1] to (short (*)[2048]).

If it's not forbidden, it's allowed. The conversion is problematic only
if the result is not properly aligned and there is no wording in the
standard indicating that arrays don't share the alignment restrictions
of their element type.

Dan
 
W

Wojtek Lerch

Dan Pop said:
Nope, in both cases. A compiler may choose to do so, for performance
reasons, but this is not a requirement. Arrays have the same alignment
as their element type:

- An array type describes a contiguously allocated nonempty set
of objects with a particular member object type, called
the element type.36) Array types are characterized by their
======================================
element type and by the number of elements in the array.
========================================================

No mention of any special alignment issues.

That's a bogus argument. The next paragraph, the one that talks about
structures, doesn't mention any special alignments issues, either. Does
that prove that a structure of two shorts cannot have stricter alignment
requirements than a single short?
Which makes sense, because,
if arr is an array of N elements, the address of its second element can
be used as the address of an array of N-1 elements (after proper
conversion).

Really? Can I have a chapter and verse, please?
 
W

Wojtek Lerch

Dan Pop said:
Keith Thompson said:
I don't believe it's possible for a short and an array of shorts to
have different required alignments. If short is 16 bits, a compiler
might choose to use, say, 32-bit alignment for arrays of shorts, but
it still has to be able to access an array of shorts that's 16-bit
aligned. For some purposes, a single short object is equivalent to an
array of 1 short.

But couldn't arrays of two or more shorts require 32-bit alignment?
Couldn't arrays of 2048 or more shorts, on the same implementation,
require
128-bit alignment?

If you declare an array of type short[2049], you should be able to
access elements 1..2048 as an array of type short[2048]. (I'm too
tired right now either to support this with citations from the
standard or to provide sample code.)

You can access those elements as if they were elements of an array of 2048
shorts, simply by ignoring the fact that it's not undefined behaviour to
subtract one from &arr[1]; but I don't think you'll find a citation to
demonstrate that it's OK to convert &arr[1] to (short (*)[2048]).

If it's not forbidden, it's allowed.

But if it's not defined, it's undefined. It's not forbidden, in the sense
that it doesn't violate a constraint; but I don't see where the result is
defined in the standard.
The conversion is problematic only
if the result is not properly aligned and there is no wording in the
standard indicating that arrays don't share the alignment restrictions
of their element type.

There's no wording that they do, either. For the few cases where the
standard requires the alignment requirements of two different types to be
identical, it's specified explicitly. Examples: a qualified and unqualified
version of the same type (6.2.5p25), a signed integer type and the
corresponding unsigned type (6.2.5p6).
 
K

kuyper

pete said:
If it's not defined, it's undefined.

Dan's right: it's not forbidden for arrays to have different alignement
requirements than their element types. Therefore, it's allowed.

In fact, the standard implies (in 6.2.5p13) that an array of two
floating point objects might have different alignment requirements than
the element type of that array. This isn't a foolproof deduction;
mentioning the array was necessary for the "same representation"
requirement, it doesn't necessarily mean that the "same alignment"
requirement also depends upon the difference between an array and a
single object.
 
D

Dan Pop

That's a bogus argument. The next paragraph, the one that talks about
structures, doesn't mention any special alignments issues, either. Does
that prove that a structure of two shorts cannot have stricter alignment
requirements than a single short?

Bogus counterexample: the standard supports structure assignment, but it
doesn't support array assignment. Arrays can be processed only on an
element by element basis.
Really? Can I have a chapter and verse, please?

What's left from the original array satisfies the definition of an array
of N-1 elements. Otherwise, the following strcpy call would be illegal:

char array[10];
strcpy(array + 1, "hello");

2 The strcpy function copies the string pointed to by s2 (including
the terminating null character) into the array pointed to by
^^^^^^^^^^^^^^
s1.

Dan
 
B

Brian Inglis

Bogus counterexample: the standard supports structure assignment, but it
doesn't support array assignment. Arrays can be processed only on an
element by element basis.

Unless the array is wrapped in a structure; people have been known to
do that. ;^>
 
W

Wojtek Lerch

Dan Pop said:
Bogus counterexample: the standard supports structure assignment, but it
doesn't support array assignment. Arrays can be processed only on an
element by element basis.

Now that we have a nice collection of bogus examples, why don't we try to
stick to the topic, please?
Really? Can I have a chapter and verse, please?

What's left from the original array satisfies the definition of an array
of N-1 elements. Otherwise, the following strcpy call would be illegal:

char array[10];
strcpy(array + 1, "hello");

2 The strcpy function copies the string pointed to by s2 (including
the terminating null character) into the array pointed to by
^^^^^^^^^^^^^^
s1.

No, the reason it's not illegal is becasue the standard specifically allows
it. The first parameter of strcpy() does not point to an array type, and
the sentence in 7.1.4p1 that describes how we should interpret the word
"array" in its description doesn't invole a requirement that it must point
to the first element of an array:

"If a function argument is described as being an array, the pointer actually
passed to the function shall have a value such that all address computations
and accesses to objects (that would be valid if the pointer did point to the
first element of such an array) are in fact valid."
 
A

Antoine Leca

En (e-mail address removed) va escriure:
Dan's right: it's not forbidden for arrays to have different
alignement requirements than their element types. Therefore, it's
allowed.

Sorry, you left me confused:

Here are Dan's words again
And now I read it saying exactly the contrary of you...


In fact, the standard implies (in 6.2.5p13) that an array of two
floating point objects might have different alignment requirements
than the element type of that array.

I do not read it this way.
I really read that a complex has the same alignment contraint as an array of
two corresponding reals, as opposed for example to a structure of two
elements (which might be otherwise an alternative implementation I could
think about.) I do not see any mention or implication that a complex could
have a different alignment constraint than the corresponding real.


Antoine
 
A

Antoine Leca

En news:[email protected], Dan Pop va escriure:
Arrays have the same alignment as their element type:
No mention of any special alignment issues. Which makes sense,
because, if arr is an array of N elements, the address of its
second element can be used as the address of an array of N-1
elements (after proper conversion).

But I fail to see how you can use this recursion argument to "jump" to the
element type: you only "proved" that all array type, whatever their size,
should have the same alignment constraints (which is not a free lunch, BTW.)
Yet I do not see why a single element could not have a (assumedly lighter)
alignement constraint.

So what did I miss?


Antoine
 
W

Wojtek Lerch

Antoine Leca said:
En news:[email protected], Dan Pop va escriure:


But I fail to see how you can use this recursion argument to "jump" to the
element type: you only "proved" that all array type, whatever their size,
should have the same alignment constraints (which is not a free lunch,
BTW.)

No, he has proved no such thing. The standard never promises that the
pointer to the second element of an array can be converted to a pointer to a
smaller array. Whether (int(*)[N-1])&arr[1] is defined behaviour depends on
whether the pointer to &arr[1] is correctly aligned to point to an array of
N-1 ints. If you want to prove that it is, you can't assume in your proof
that the conversion is defined.
 

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,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top