Is it legal to access a 4-byte int at any offset (alignment) in the
following array:
char arr[8] = {0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1};
?? (See question 3 later...)
Example:
printf("%08x\n", *((int *) (arr + 0)));
printf("%08x\n", *((int *) (arr + 1)));
printf("%08x\n", *((int *) (arr + 2)));
printf("%08x\n", *((int *) (arr + 3)));
/*
Output assuming the following
~32 bit natural word size of processor
~little endian: the address of a single byte 'Q' corresponds with the
adress of a 4-byte int only, if that int has this same byte 'Q' as the
LSB
0d0c0b0a
0e0d0c0b
0f0e0d0c
000f0e0d
*/
4 Questions:
* assume 32-bit processor: natural word size is 4 bytes
* alignment: a 4-byte int is aligned if it lies on an address that is
a multiple of 4
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)???
(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?
~any other possibilities?
2)
~Will "short sh;" (where short has 2 bytes) always be 4-byte aligned
(according to the natural word size)???
~If not, and one desires it to be 4-byte aligned, one could use:
int tmp;
#define sh ( *((short *)(&tmp)) )
~would that work?
~are there any other possibilities?
3)
*((int *) (arr + 1)) can be an unaligned 4-byte int-access (see
above). As can be seen above, it works with my gcc compiler. I believe
it splits into 2 accesses (that are then combined).
~Will it work on every standards-compliant C compiler (assuming int is
4 bytes)?
//That was a read.
//Now a write:
~ Is this legal:
int i;
*((int *)(arr+1)) = i;
? (It works with gcc!)
Does it depend on the C-compiler? Or on the processor? or...?
4)
(gcc...)
struct struc_a {
char a; /*1 byte */
short b; /*2 bytes*/
char c; /*3 bytes*/
} __attribute__ ((packed));
/*gcc extension*/
/* sizeof(struct struc_a) is 4. */
~Will "struct struc_a tmp" be 4-byte aligned?
~gcc: Could one align "struct struct_a tmp" so that it lies at an
addess x,
where x % 4 = 1 ?
---- Offtopic: ----
Are there any good books that can be recommended on C programming and
in particular how this relates to the actual machine code generated?
Things like:
alignment, byte-ordering, portable C programming, how loops are
implemented in machine code, optimization
I wonder if reading the C standard is beneficial (or in what respect
it would be beneficial)?
I'm really impressed by some people, who quote relevant information
directly from the standard!
Or reading a book on GCC?
Or maby Jens Schweikhardt's book, if it's ever finished:
http://www.schweikhardt.net/#mybook
Or Knuth's output?
?
At this point I think that practical programming combined with
comp.lang.c is the best resource, thanks to some really intelligent
people giving quality comments.
?
But still: I'm pretty sure going to have a *real* look at assembly
language and some debugger tools in the near future.
Thanks -Albert
A four-byte type has an alignment requirement of 4,
2, or 1 bytes (the platform decides, and doesn't tell
you). Therefore, at least one of the offsets in the
array will be properly aligned for an int, if int is
four bytes wide.
> 4 Questions:
> * assume 32-bit processor: natural word size is 4 bytes
> * alignment: a 4-byte int is aligned if it lies on an address that is
> a multiple of 4
>
> 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.
You can acquire memory from malloc() et al., and this
will be aligned strictly enough for the most restrictive of
all C types (whatever that is). Again, this is not guaranteed
to have 4-byte alignment.
> 2)
> ~Will "short sh;" (where short has 2 bytes) always be 4-byte aligned
> (according to the natural word size)???
A two-byte type requires either 2-byte or 1-byte
alignment. The compiler is not required to align it more
restrictively than the type needs.
> ~If not, and one desires it to be 4-byte aligned, one could use:
> int tmp;
> #define sh ( *((short *)(&tmp)) )
>
> ~would that work?
> ~are there any other possibilities?
See above. It's easy to get a group of objects aligned
so as to satisfy the strictest among them, but I can think
of no portable way to ensure 4-byte alignment.
> 3)
> *((int *) (arr + 1)) can be an unaligned 4-byte int-access (see
> above). As can be seen above, it works with my gcc compiler. I believe
> it splits into 2 accesses (that are then combined).
> ~Will it work on every standards-compliant C compiler (assuming int is
> 4 bytes)?
No.
> Does it depend on the C-compiler? Or on the processor? or...?
Yes.
> 4)
> (gcc...)
>
> struct struc_a {
> char a; /*1 byte */
> short b; /*2 bytes*/
> char c; /*3 bytes*/
> } __attribute__ ((packed));
>
> /*gcc extension*/
>
> /* sizeof(struct struc_a) is 4. */
>
> ~Will "struct struc_a tmp" be 4-byte aligned?
Ask in a gcc group.
> ~gcc: Could one align "struct struct_a tmp" so that it lies at an
> addess x,
> where x % 4 = 1 ?
Ask in a gcc group.
> Hello!
>
> Is it legal to access a 4-byte int at any offset (alignment) in the
> following array:
No. In effect, all your other questions dissolve, but I'll go through
them...
> 4 Questions:
> * assume 32-bit processor: natural word size is 4 bytes
> * alignment: a 4-byte int is aligned if it lies on an address that is
> a multiple of 4
>
> 1)
> ~Will "char arr[8]" always be 4-byte aligned (according to the natural
> word size)???
You can't rely on that.
> ~Or will it rather be 1-byte aligned (meaning it can lie where it
> wants)???
It may be. It may also be aligned in some other way.
> (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?
> ~any other possibilities?
See the recent thread. What are you really trying to do? There may
be a simple answer for you problem.
> 2)
As above.
> 3)
> *((int *) (arr + 1)) can be an unaligned 4-byte int-access (see
> above). As can be seen above, it works with my gcc compiler. I believe
> it splits into 2 accesses (that are then combined).
> ~Will it work on every standards-compliant C compiler (assuming int is
> 4 bytes)?
No. Use memcpy (or memmove if overlap is possible):
int i;
memcpy(&i, arr + 1, sizeof i);
> //That was a read.
>
> //Now a write:
> ~ Is this legal:
> int i;
> *((int *)(arr+1)) = i;
> ? (It works with gcc!)
> Does it depend on the C-compiler? Or on the processor? or...?
Ditto: memcpy(arr + 1, &i, sizeof i);
> 4)
> (gcc...)
>
> struct struc_a {
> char a; /*1 byte */
> short b; /*2 bytes*/
> char c; /*3 bytes*/
> } __attribute__ ((packed));
>
> /*gcc extension*/
>
> /* sizeof(struct struc_a) is 4. */
>
> ~Will "struct struc_a tmp" be 4-byte aligned?
> ~gcc: Could one align "struct struct_a tmp" so that it lies at an
> addess x,
> where x % 4 = 1 ?
Gcc has was for control alignment. They are off topic here. A gcc
groups will be able to tell you more than you want to know about this!
> ---- Offtopic: ----
> Are there any good books that can be recommended on C programming and
> in particular how this relates to the actual machine code generated?
Some would say that such a book would be, by definition, not good. I
would probably not go quite that far, but C has been plagued by its
appeal to those that prefer to fiddle than to write portable code.
<snip>
--
Ben.
>> (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?
>> ~any other possibilities?
>
> See the recent thread. What are you really trying to do? There may
> be a simple answer for you problem.
OK, bad form, but it might cut down on the noise... I see, reading
Eric Sossman's reply, that I miss-read your code. I thought you were
using the int array for force alignment of a following declaration.
The other alignment thread is not relevant.
The pointer in 'arr' will be aligned for an int.
--
Ben.
just to put it into code (in case someone else is wondering)
union myunion {
char arr[8];
int arr_tmp[2];
};
union myunion uni = {{0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1}};
char *arr = uni.arr;
> You can acquire memory from malloc() et al., and this
> will be aligned strictly enough for the most restrictive of
> all C types (whatever that is). Again, this is not guaranteed
> to have 4-byte alignment.
#include <stdlib.h>
#include <string.h>
#define LEN 9
{
char *arr = (char *) malloc(LEN);
memcpy(arr, (char[]) {0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2}, LEN);
free(arr);
}
> > 2)
> > ~Will "short sh;" (where short has 2 bytes) always be 4-byte aligned
> > (according to the natural word size)???
>
> A two-byte type requires either 2-byte or 1-byte
> alignment. The compiler is not required to align it more
> restrictively than the type needs.
>
> > ~If not, and one desires it to be 4-byte aligned, one could use:
> > int tmp;
> > #define sh ( *((short *)(&tmp)) )
>
> > ~would that work?
> > ~are there any other possibilities?
>
> See above. It's easy to get a group of objects aligned
> so as to satisfy the strictest among them, but I can think
> of no portable way to ensure 4-byte alignment.
union myunion2 {
short a;
int tmp;
};
union myunion2 mu2;
#define sh (mu2.a)
or
#include <stdlib.h>
#include <string.h>
#define sh (*sh_ptr)
{
short *sh_ptr = (short *) malloc(sizeof(short));
free(sh_ptr);
}
Thanks -Albert
No. You can only portably read a 4-byte int value from addresses that
are correctly aligned for reading such a value.
<snip>
> 4 Questions:
> * assume 32-bit processor: natural word size is 4 bytes
> * alignment: a 4-byte int is aligned if it lies on an address that is
> a multiple of 4
>
> 1)
> ~Will "char arr[8]" always be 4-byte aligned (according to the natural
> word size)???
No.
> ~Or will it rather be 1-byte aligned (meaning it can lie where it
> wants)???
Yes.
There are two important properties to alignment in C.
- The alignment requirements on an array are the same as those of the
element type of the array.
- The alignment requirements on a type T can not be stricter than the
size of the type (i.e. align_of(T) <= sizeof(T) ).
Because char is defined to have size 1, you must be able to place a
char object anywhere in the memory and the same holds for an array of
char.
>
> (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?
Yes, that would cause arr to point at 4-byte aligned memory.
> ~any other possibilities?
As Eric already indicated, unions and malloc().
>
> 2)
> ~Will "short sh;" (where short has 2 bytes) always be 4-byte aligned
> (according to the natural word size)???
No.
> ~If not, and one desires it to be 4-byte aligned, one could use:
> int tmp;
> #define sh ( *((short *)(&tmp)) )
>
> ~would that work?
No. Casting an int* to a short* and dereferencing the result causes
Undefined Behaviour.
> ~are there any other possibilities?
Same as before. Use a union or malloc().
>
> 3)
> *((int *) (arr + 1)) can be an unaligned 4-byte int-access (see
> above). As can be seen above, it works with my gcc compiler. I believe
> it splits into 2 accesses (that are then combined).
> ~Will it work on every standards-compliant C compiler (assuming int is
> 4 bytes)?
No. It will not even work on all platforms that GCC can produce code
for.
> //That was a read.
>
> //Now a write:
> ~ Is this legal:
> int i;
> *((int *)(arr+1)) = i;
> ? (It works with gcc!)
> Does it depend on the C-compiler? Or on the processor? or...?
It depends very heavily on the processor.
Some processor have no alignment restrictions at all, so they can
access any type of object at any address.
Some processors impose a performance penalty for unaligned access.
Some processors simply do not allow unaligned access at all.
<snip - GCC specific question. Should be asked in a GCC group>
> ---- Offtopic: ----
> Are there any good books that can be recommended on C programming and
> in particular how this relates to the actual machine code generated?
>
> Things like:
> alignment, byte-ordering, portable C programming, how loops are
> implemented in machine code, optimization
These books probably do exist, but they are by definition highly
platform/processor specific.
>
> I wonder if reading the C standard is beneficial (or in what respect
> it would be beneficial)?
Reading the standard can be beneficial if you want to know what is
guaranteed to be true across *all* platforms and C compilers.
>
> Thanks -Albert
Bart v Ingen Schenau
One last question:
Is a struct aligned according to its size, or according to the largest
component it contains:
Example:
What about a struct that has a sizeof 4 bytes, but contains at most a
2-byte short:
Will it be 2-byte short aligned? Or rather: will it be 4-byte aligned
since the whole structure has 4 bytes?
What if a struct contains a char-array of 4 elements? Will that be 4-
byte aligned or char aligned?
((Is this different with unions?))
On Aug 29, 9:22 am, Bart van Ingen Schenau
<Bart.van.Ingen.Sche...@ict.nl> wrote:
> No. Casting an int* to a short* and dereferencing the result causes
> Undefined Behaviour.
OK that goes against what I expect from my processors!
Is it rare that this causes undefined behaviour? (Perhaps only on old
extremely limited processors...?)
Thanks -Albert
Relevant code snippets (if necessary) can be found (gnu.gcc.help)
here:
http://groups.google.com/group/gnu.gcc.help/browse_thread/thread/d823eb799e1b4117/2a1c268089b80017#2a1c268089b80017
-Albert
Each element of the struct is correctly aligned within
the struct itself. This implies that the alignment requirements
of the elements must all be divisors of the struct's own
alignment requirement. Therefore, the struct's alignment
requirement is divisible by the least common multiple of its
elements' alignment requirements.
Often, the struct's alignment *is* the l.c.m. of the
element alignments, and since alignment requirements are
usually powers of two this means the struct's alignment is
the same as its strictest element's alignment. But C does
not guarantee this; all you can be sure of is that the struct
alignment is a multiple of the l.c.m.
> Example:
> What about a struct that has a sizeof 4 bytes, but contains at most a
> 2-byte short:
> Will it be 2-byte short aligned? Or rather: will it be 4-byte aligned
> since the whole structure has 4 bytes?
Its alignment requirement will be either 4, 2, or 1 byte.
> What if a struct contains a char-array of 4 elements? Will that be 4-
> byte aligned or char aligned?
Its alignment requirement will be either 4, 2, or 1 byte.
> ((Is this different with unions?))
Not in any way I can see. Just as with structs, a union must
be properly aligned for all its elements, so the union's alignment
is a multiple of the l.c.m. of the element alignments. Again, the
multiplier is often unity.
--
Eric Sosman
eso...@ieee-dot-org.invalid
No typing error: I wrote what I meant. On some machines,
a `short' can start at any address; on others, it must start
at an even address. On machines where sizeof(short) > 2 --
I don't know of any, but I know only a few of the zillions
of machines -- `short' might need even more restrictive
alignment.
> If a 2-byte short has an alignment requirement of 2, and the struct
> has 4 bytes,
> then the struct will have an alignment requirement of 2, 4, etc.
Strike the "etc." A type's alignment requirement must
be a divisor of its size (otherwise, arrays of that type
wouldn't work). It follows that your four-byte struct cannot
require alignment stricter than four bytes. Considering the
divisibility requirement, a four-byte struct -- any four-
byte object, in fact -- must have an alignment requirement
of four, two, or one byte. Period. No threes, no eights.
> Example:
>
> struct mystruct {
> short b;
> char a;
> char c;
> };
>
> OR
>
> struct mystruct {
> char a;
> short b;
> char c;
> };
> which
> C will stuff as follows
s/will/may/
s/follows/it pleases/
> struct mystruct {
> char a;
> char stuff1;
> short b;
> char c;
> char stuff2;
> };
>
>
>
>
>>>What if a struct contains a char-array of 4 elements? Will that be 4-
>>>byte aligned or char aligned?
>>
>> Its alignment requirement will be either 4, 2, or 1 byte.
>
>
> Yes, since the alignment req. of a char-array is 1 byte.
"No," actually, because I overlooked something obvious.
Given `struct s { char c[4]; }' it is not guaranteed that
sizeof(struct s) == 4: there could be padding after the
array, making the struct larger than four bytes. In that
case, the alignment requirement would be some divisor of
that larger size. If sizeof(struct s) == 15, the alignment
requirement will be one of 1, 3, 5, or 15; 2 and 4 would
not be possibilities.
> Here's something interesting:
>
> struct structi {
> short a; //2 bytes
> int b; //4bytes
> short c; //2bytes
> } __attribute__ ((packed));
As has been suggested before, you should ask about
gcc-specific extensions to C in a gcc-specific forum,
not here.
Even a 2-byte short?
>
> > If a 2-byte short has an alignment requirement of 2, and the struct
> > has 4 bytes,
> > then the struct will have an alignment requirement of 2, 4, etc.
>
> Strike the "etc." A type's alignment requirement must
> be a divisor of its size (otherwise, arrays of that type
> wouldn't work). It follows that your four-byte struct cannot
> require alignment stricter than four bytes. Considering the
> divisibility requirement, a four-byte struct -- any four-
> byte object, in fact -- must have an alignment requirement
> of four, two, or one byte. Period. No threes, no eights.
Makes sense, thanks.
After all this, here's my personal definition:
(Assuming byte-adresses:)
A structure has an alignment requirement of X bytes, if it can lie at
addresses y, such that:
y%X = 0
y mod X = 0
So for structs, one can define: A (unpacked **) struct has an
alignment requirement of X bytes,
where X is a divisor of the structure's size in bytes. X itself must
be divisible by the "the least common multiple of the structure's
elements' alignment requirements" (in bytes).
All of the structure's elements have to satisfy their alignment req.,
so that padding is added where necessary:
Only if the structure is padded like that, can it be guaranteed, that
the structure's size is a multiple of "the least common multiple of
the structure's elements' alignment requirements":
(Only then can an X satisfying the above conditions be found.)
Even when all the elements are already correctly aligned, additional
padding could still be added, but it must be padded, such that an X
satisfying the above conditions can be found (must exist).
(unpacked **) - above means: padded where necessary
-Albert
Yes. Even an N-byte short.
"anon.asdf" probably has such a machine: The Intel x86 processor doesn't
need any alignment on any of its data types. Accessing aligned data is a
bit faster than accessing unaligned data, which is why compilers usually
align 16 bit types on even addresses, 32 bit types on addresses
dividable by 4, etc. But from a functional POV that isn't necessary, and
I think "1 byte alignment for everything" was even the default for some
8086 compilers.
hp
--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | h...@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
> anon...@gmail.com wrote On 08/29/07 10:46,:
> > On Aug 29, 1:58 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> >
> >>anon.a...@gmail.com wrote:
> >>[...]
> >>>Example:
> >>>What about a struct that has a sizeof 4 bytes, but contains at most a
> >>>2-byte short:
> >>>Will it be 2-byte short aligned? Or rather: will it be 4-byte aligned
> >>>since the whole structure has 4 bytes?
> >>
> >> Its alignment requirement will be either 4, 2, or 1 byte.
> >
> > 1 byte???
> > This implies that a 2-byte short can have an alignment requirement of
> > 1 byte!
> > Hmmm...
> > That is probably a small typing error (because it would imply that
> > this 2-byte short can lie anywhere, even "edging" across the
> > processors "natural word divisions" - usually sizeof(int)), right?
>
> No typing error: I wrote what I meant. On some machines,
> a `short' can start at any address; on others, it must start
> at an even address.
And there could even be - but probably are not right now - machines
where it must start at an odd address.
Richard
But not if any other type must start at an even address.
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
> r...@hoekstra-uitgeverij.nl (Richard Bos) writes:
> > Eric Sosman <Eric....@sun.com> wrote:
> [...]
> >> No typing error: I wrote what I meant. On some machines,
> >> a `short' can start at any address; on others, it must start
> >> at an even address.
> >
> > And there could even be - but probably are not right now - machines
> > where it must start at an odd address.
>
> But not if any other type must start at an even address.
True. Unless the compiler hacks accesses to shorts which start structs
around like nobody's business, but that's even less likely.
Richard
It's impossible. Suppose short requires an odd address, and int
requires an even addresss. Then there's no way to allocate an object
of type 'union { short s; int i; }', or to allocate both shorts and
ints via malloc.
If the compiler works around the alignment restriction by, say,
accessing shorts a byte at a time, then shorts don't require odd
addresses.
What is possible, assuming the hardware imposes such odd (ahem)
requirements, is that the compiler can allocate shorts at odd
addresses whenever it can, and put them at even addresses only when
necessary. The *preferred* alignment for a given type may differ from
the *required* alignment for that same type.
On any hardware, it's possible for the compiler to impose only byte
alignment on all types, as long as it generates the (possibly slow and
bulky) code necessary to deal with this.
But the C standard does not allow for this: its concept of alignment is
the requirement that an object of a given type start at a multiple of
some particular number of bytes.
-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
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.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com
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.
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;
>
>
>> You can acquire memory from malloc() et al., and this
>> will be aligned strictly enough for the most restrictive of
>> all C types (whatever that is). Again, this is not guaranteed
>> to have 4-byte alignment.
>
>
>#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
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.
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.
My first example (preserved above) did. That was not a 2 byte int,
just an int. Also note the size of a double.
>>> Imagine a system with 9 bit chars, such that:
>>>
>>> sizeof is
>>> ====== ==
>>> int 3
...
>>> double 6
>> 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.
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.
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.