Alignment, Cast

K

Keith Thompson

CBFalconer said:
Chapter and verse please. I think you can come to this conclusion
only by making some earlier assumptions about the memory system.
AFAIK the only stricture is that malloc returns an address aligned
for ALL types.

C99 3.2:

alignment

requirement that objects of a particular type be located on
storage boundaries with addresses that are particular multiples of
a byte address

As has been discussed here, this glosses over just what it means for
an address to be a "multiple" of a byte address, but it seems to allow
for alignments like 2N while excluding alignments like 2N+1.
 
B

Barry Schwarz

(e-mail address removed) wrote On 08/28/07 10:49,:
1)
~Will "char arr[8]" always be 4-byte aligned (according to the natural
word size)???
~Or will it rather be 1-byte aligned (meaning it can lie where it
wants)???

The latter. Since `char' needs only 1-byte alignment,
the compiler does not need to align it more strictly.
(thinking ahead...) If not 4-byte aligned, but one desires a 4 byte
alignment, then one would have to use:
int arr_tmp[2];
char *arr = (char *)arr_tmp;
~would that work?

It would align the "`char' array" strictly enough for
an int. Under your assumption this means 4-byte alignment,
but that may not be true of all C implementations, or even
of all C implementatins where sizeof(int)==4.
~any other possibilities?

You can use a union to place objects of several types
at the same address, aligned well enough for the strictest
among them -- but it's not guaranteed that this will achieve
4-byte alignment.

just to put it into code (in case someone else is wondering)

union myunion {
char arr[8];
int arr_tmp[2];

This need not be an array of int. A simple int will be sufficient to
force alignment to whatever is appropriate for an int. On the outside
chance that sizeof(int) is greater than 4, the array causes the union
to be larger than necessary.
};

union myunion uni = {{0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1}};

char *arr = uni.arr;




#include <stdlib.h>
#include <string.h>

#define LEN 9
{
char *arr = (char *) malloc(LEN);

Don't cast the return from malloc.



Remove del for email
 
C

CBFalconer

Keith said:
C99 3.2:

alignment

requirement that objects of a particular type be located on
storage boundaries with addresses that are particular multiples of
a byte address

As has been discussed here, this glosses over just what it means for
an address to be a "multiple" of a byte address, but it seems to allow
for alignments like 2N while excluding alignments like 2N+1.

That only covers alignment for one particular type. For something
like malloc you need different rules. Imagine a system with 9 bit
chars, such that:

sizeof is
====== ==
short 2
int 3
long 4
float 4
double 6

which would require a universal alignment multiple of 12. Note
that I have not specified the maximums for those various types. As
described above there is room for at least two trapping bits,
allowing detection of uninitialized use, etc.

In practice actual memory systems have their own width, which needs
to be sufficient to allow for ECC coding for all items other than
bytes. This expands an 8 octet unit to be at least 72 bits. Two
different reading (and writing) methods are needed if the ECC bits
are to be visible to the system. In this case the system MIGHT
look like:

sizeof is live binary bits
====== == ================
char 1 9
short 3 24
int 4 32
long 6 48
long long 8 64
float 4 whatever
double 8 whatever

and the alignment multiple for malloc needs to be 12 again.

At any rate, there is room to play about, and possibly arrange for
a truly universal international char. set. If I have anything to
say about it, such a set will have made adequate allowance for ECC
checking.

At any rate, the standard has sufficient room to allow all sorts of
memory arrangements with various practical advantages.
 
K

Keith Thompson

CBFalconer said:
That only covers alignment for one particular type. For something
like malloc you need different rules.

For malloc, you just need an alignment that's consistent with the
alignment of all types, at least the least common multiple of all
alignments.
Imagine a system with 9 bit
chars, such that:

sizeof is
====== ==
short 2
int 3
long 4
float 4
double 6

which would require a universal alignment multiple of 12. Note
that I have not specified the maximums for those various types. As
described above there is room for at least two trapping bits,
allowing detection of uninitialized use, etc.

You've only specified the sizes. Are you assuming that each type must
be aligned to its size (e.g., double requires 6-byte alignment)?
In practice actual memory systems have their own width, which needs
to be sufficient to allow for ECC coding for all items other than
bytes. This expands an 8 octet unit to be at least 72 bits. Two
different reading (and writing) methods are needed if the ECC bits
are to be visible to the system. In this case the system MIGHT
look like:

sizeof is live binary bits
====== == ================
char 1 9
short 3 24
int 4 32
long 6 48
long long 8 64
float 4 whatever
double 8 whatever

and the alignment multiple for malloc needs to be 12 again.

Why would you want ECC bits to be visible to C software? You can't
meaningfully set them or read them, can you?

But ok, I suppose they could be treated as padding bits, so short has
a width of 24 bits plus 3 padding bits. But alignments are in terms
of bytes, so I don't see how padding bits are relevant. (The
standard's concept of padding bits doesn't apply to floating-point
types, but they can still have bits that don't contribute to the
value.)
At any rate, there is room to play about, and possibly arrange for
a truly universal international char. set. If I have anything to
say about it, such a set will have made adequate allowance for ECC
checking.

At any rate, the standard has sufficient room to allow all sorts of
memory arrangements with various practical advantages.

Not *all* sorts. In particular, it doesn't allow an implementation to
require a 2-byte type (say short) to be allocated at an odd address,
since it would violate the definition of "alignment". That was the
point I was making above; I don't believe you addressed it.
 
C

CBFalconer

Keith said:
.... snip ...

.... snip ...

Not *all* sorts. In particular, it doesn't allow an implementation to
require a 2-byte type (say short) to be allocated at an odd address,
since it would violate the definition of "alignment". That was the
point I was making above; I don't believe you addressed it.

My first example (preserved above) did. That was not a 2 byte int,
just an int. Also note the size of a double.
 
R

Richard Tobin

Not *all* sorts. In particular, it doesn't allow an implementation to
require a 2-byte type (say short) to be allocated at an odd address,
since it would violate the definition of "alignment". That was the
point I was making above; I don't believe you addressed it.
[/QUOTE]
My first example (preserved above) did. That was not a 2 byte int,
just an int.

If ints are 3 bytes, they might require multiple-of-3 alignment, but
that's not what we're talking about. We're talking about requiring
*odd* addresses, i.e. ones of the form 2n+1.
Also note the size of a double.

Again, multiples of 6 are not odd.

-- Richard
 
K

Keith Thompson

CBFalconer said:
My first example (preserved above) did. That was not a 2 byte int,
just an int. Also note the size of a double.

I think you've misunderstood my point.

If we assume that all the types must be aligned to their size (I asked
you if you were assuming that), then you've shown that a type can have
an alignment that's not a multiple or factor of some other type's
alignment. That's not what I was talking about.

In your example, a short (with 2-byte size and alignment) can be at
address 2, 4, 6, 8, etc. An int (with 3-byte size and alignment) can
be at address 3, 6, 9, 12, etc. In each case, the required address is
a whole multiple of some constant (again, glossing over just what that
means).

What isn't allowed is for an implementation to require a short to be
at address 1, 3, 5, 7, etc. (a short at address 2 or 4 would be
misaligned), or for an int to be at address 4, 7, 10, 13, etc. (an int
at address 3 or 6 would be misaligned), because that would violate the
standard's definition of "alignment". That was my point, and that's
what you didn't address.
 
C

CBFalconer

Keith said:
.... snip ...

I think you've misunderstood my point.

If we assume that all the types must be aligned to their size (I asked
you if you were assuming that), then you've shown that a type can have
an alignment that's not a multiple or factor of some other type's
alignment. That's not what I was talking about.

In your example, a short (with 2-byte size and alignment) can be at
address 2, 4, 6, 8, etc. An int (with 3-byte size and alignment) can
be at address 3, 6, 9, 12, etc. In each case, the required address is
a whole multiple of some constant (again, glossing over just what that
means).

What isn't allowed is for an implementation to require a short to be
at address 1, 3, 5, 7, etc. (a short at address 2 or 4 would be
misaligned), or for an int to be at address 4, 7, 10, 13, etc. (an int
at address 3 or 6 would be misaligned), because that would violate the
standard's definition of "alignment". That was my point, and that's
what you didn't address.

Agreed, which leaves very little to argue about. :) At least one
of us got around to making the subject clear.
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top