pointer alignment when int != char *
Author |
Message |
Simon Bro #1 / 27
|
 pointer alignment when int != char *
If I were to want to implement malloc (or some such) on a machine where sizeof(int) != sizeof(char *), how do I ensure that the pointer-values I return are maximally aligned (eg, quad-aligned)? If sizeof(int)==sizeof(char *), then I can cast the pointer to an int, do whatever arithmetic stuff is required to it to get it to be aligned, then cast it back again - but of course this won't work if information is lost by either of the casts. Any hints? (BTW, It's not really malloc I'm dealing with, I just lied about that one) %{ Simon! %} -- ---------------------------------- | Simon Brown | UUCP: seismo!mcvax!ukc!its63b!simon
| Scotland, UK. | ---------------------------------- "Life's like that, you know"
|
Tue, 17 Nov 1992 04:39:00 GMT |
|
 |
Bob Lars #2 / 27
|
 pointer alignment when int != char *
Quote:
>If I were to want to implement malloc (or some such) on a machine where >sizeof(int) != sizeof(char *), how do I ensure that the pointer-values I >return are maximally aligned (eg, quad-aligned)?
The same way as you would on any other machine: non-portably. (What is your definition of quad-aligned? 4 * sizeof(char)? There are quit a few machines where this is not maximally aligned.) For example, prime 64v mode: char *alignpointer(p) char *p; { union { char *up; struct { unsigned fault:1; unsigned ring:2; /* I may have the ring and extend bits exchanged */ unsigned extend:1; /* check before you try this on a real prime */ unsigned segment:12; unsigned offset:16; unsigned bit:4; unsigned unused:12; } point; } un; int zerooffset; un.up = p; if(un.point.fault) return p; /* faulted pointer, not a valid address */ zerooffset = un.point.offset == 0; un.point.offset = (un.point.offset | (un.point.extend & (un.point.bit!=0)) + 1) & ~1; /* round offset up to next 4 byte boundry */ un.point.extend = 0;/* and say it is at a 2-byte boundry */ un.point.bit = 0; /* unneded, but leave it clean */ if(un.point.offset == 0 && !zerooffset) un.point.segment++; return un.up; Quote: }
Obviously, it would be easier to make sure to generate aligned pointers in the first place. Also I did not make all the assumptions that the C compiler does, assuming you could have gotten the pointer via another language.
Uucp: {sdcrdcf,seismo!cit-vax}!oberon!castor!blarson "How well do we use our freedom to choose the illusions we create?" -- Timbuk3
|
Thu, 17 Dec 1992 19:24:00 GMT |
|
 |
Doug Gwy #3 / 27
|
 pointer alignment when int != char *
Quote:
>If I were to want to implement malloc (or some such) on a machine where >sizeof(int) != sizeof(char *), how do I ensure that the pointer-values I >return are maximally aligned (eg, quad-aligned)? If sizeof(int)==sizeof(char *), >then I can cast the pointer to an int, do whatever arithmetic stuff is >required to it to get it to be aligned, then cast it back again - but of >course this won't work if information is lost by either of the casts.
First, do most of your arithmetic on (char *) data types, not on (int)s. Second, forcing alignment may require converting your pointers to integral types to do the rounding operations. (long) is appropriate for portable code. (If a (char *) won't fit into a (long), you have real problems!) Third, it is difficult to portably determine alignment requirements. Consider using something like the following: struct align { char c0; union { long l1[2]; double d1[2]; char *cp1[2]; union { long l2[2]; double d2[2]; char *cp2[2]; } u1[2]; } u0; } a; #define ALIGN ((char *)&a.u0 - (char *)&a.c0) (This example can probably be improved.)
|
Thu, 17 Dec 1992 16:33:00 GMT |
|
 |
Larry McV #4 / 27
|
 pointer alignment when int != char *
Quote: >integral types to do the rounding operations. (long) is appropriate >for portable code. (If a (char *) won't fit into a (long), you have >real problems!)
I'm not sure this is true anymore. Don't some supercomputers make longs 32 bits, long longs 64 bits, and have addresses > 32 bits and < 64 bits? I seem to remember that someone said something like that recently.
|
Thu, 17 Dec 1992 20:13:00 GMT |
|
 |
Castor L. #5 / 27
|
 pointer alignment when int != char *
Quote:
>>integral types to do the rounding operations. (long) is appropriate >>for portable code. (If a (char *) won't fit into a (long), you have >>real problems!) >I'm not sure this is true anymore. Don't some supercomputers make >longs 32 bits, long longs 64 bits, and have addresses > 32 bits and < 64 bits? >I seem to remember that someone said something like that recently.
Well, I am not positive about how the C compiler is organized, (who wants to use a compiler which can barely vectorize on a cray?) However, the fortran compiler's primary data type for integers is 64 bits wide. Internally, the addressing registers are only 24 bits wide. (The machine has no virtual memory, and 24 bits addresses 16 megawords which is still 128Mbytes, so the need for 32 bit or 64 bit addressing is questionable.) Anyways this has lead to much grief for myself when I found library routines which never expected to see things bigger than 8 Megwords (since the integers are signed.). So I guess the m{*filter*}of the story is that sizeof ( char *) < sizeof(int) is also quite possible in some wierd implementations. -Castor Fu
|
Thu, 17 Dec 1992 21:07:00 GMT |
|
 |
Doug Gwy #6 / 27
|
 pointer alignment when int != char *
->integral types to do the rounding operations. (long) is appropriate ->for portable code. (If a (char *) won't fit into a (long), you have ->real problems!) - -I'm not sure this is true anymore. Don't some supercomputers make -longs 32 bits, long longs 64 bits, and have addresses > 32 bits and < 64 bits? -I seem to remember that someone said something like that recently. What's a (long long)? We were talking about portable code!
|
Thu, 17 Dec 1992 21:51:00 GMT |
|
 |
Larry McV #7 / 27
|
 pointer alignment when int != char *
I sez: I'm not sure this is true anymore. Don't some supercomputers make longs 32 bits, long longs 64 bits, and have addresses > 32 bits and < 64 bits? I seem to remember that someone said something like that recently. Doug sez: What's a (long long)? We were talking about portable code! A long long is a kludge. However, I seem to remember that it went something like this: a company was doing unix on a Amdahl (???) and the unix people were really used to (xxx *) == 32 bits and (long) == 32 bits, and having it otherwise broke all sorts of code. So they gave people short, int, long, and long long. Yeah, it's gross. But so was defining C in such an ambiguous way. It's really time for int8 int16 int32 int64 or some such attempt at defining sizes with the type.
|
Thu, 17 Dec 1992 11:36:00 GMT |
|
 |
Karl Heu #8 / 27
|
 pointer alignment when int != char *
Quote:
>>(long) is appropriate for portable code. (If a (char *) won't fit into a >>(long), you have real problems!)
Hasn't ANSI removed all pretense of pointers being integerizable? Quote: >I'm not sure this is true anymore. Don't some supercomputers make >longs 32 bits, long longs 64 bits, and have addresses > 32 bits and < 64 bits? >I seem to remember that someone said something like that recently.
Probably my article, which was hypothetical. I was less concerned with the cast of pointer to int, which is nonportable anyway, than with the kosherness of having size_t and ptrdiff_t be larger than unsigned long.
|
Thu, 17 Dec 1992 19:31:00 GMT |
|
 |
g.. #9 / 27
|
 pointer alignment when int != char *
Quote:
>Hasn't ANSI removed all pretense of pointers being integerizable?
No -- it doesn't REQUIRE that they be, but it does provide some constraints in the case that the implementation supports this (as many do).
|
Thu, 17 Dec 1992 15:20:00 GMT |
|
 |
r.. #10 / 27
|
 pointer alignment when int != char *
That is hideous. I don't know what supercomputer you are referring to but Crays have ints and longs both at 64 bits. There are no super-longs. When we did the compilers for the HEP Supercomputer (64 bit words), we opted for 16 bit shorts, 64 bit ints, and 64 bit longs. There is one more hardware supported type (half words-32 bits). Avoiding things that would really warp the language such as short long ints or long short ints, and realizing that we really wanted int to be 64 bits (the convenient size as stated in K&R and the standards), we settled for a seperate "hidden" type that we try to avoid using except when necessary. It was called _int32, though the term "medium int" did come up in discussion. By the way, it was a real pain hacking pcc to do the extra int type. -Ron
|
Thu, 17 Dec 1992 14:17:00 GMT |
|
 |
William E. Davidsen #11 / 27
|
 pointer alignment when int != char *
: That is hideous. I don't know what supercomputer you are referring : to but Crays have ints and longs both at 64 bits. There are no super-longs. : When we did the compilers for the HEP Supercomputer (64 bit words), : we opted for 16 bit shorts, 64 bit ints, and 64 bit longs. There is : one more hardware supported type (half words-32 bits). Avoiding things... Why not have int be 32 bits? That fits the requirement that length char<=short<=int<=long. Not a comment, just a question... --
{chinet | philabs | sesimo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
|
Thu, 17 Dec 1992 16:06:00 GMT |
|
 |
Doug Gwy #12 / 27
|
 pointer alignment when int != char *
Quote: >Why not have int be 32 bits? That fits the requirement that >length char<=short<=int<=long. Not a comment, just a question...
There are two main considerations for the correct size to be used for (int) when implementing C on a new system: 1. (int) objects should be accessible quickly. On a word-addressed architecture, this argues for making them full words. 2. (int)s must be usable for indexing arrays. Depending on the address space, one may have to either impose an artificial limit on array sizes or else make (int)s longer than they might have been. For example, on a hypothetical PDP-11AX (which doesn't exist because it turned into a VAX), one could have had 16 bits continue to be the natural integer data size but 24 or 32 bits could have been the preferred pointer size due to an extended addressing scheme using base registers a la Gould. The C implementor would almost certainly have wanted to make the larger address space available on such a machine, which would force some sort of accommodation to be made for indexing char arrays -- probably by making (int)s as wide as char pointers. I understand from hearsay that the IBM PC world (actually the Intel 8086 world) ran against this very problem, and instead of making a single sane choice they ended up proliferating a variety of incompatible sets of choices (hilariously called "models"). One hopes that a lesson was learned, but I doubt it.
|
Thu, 17 Dec 1992 16:58:00 GMT |
|
 |
Ron Natal #13 / 27
|
 pointer alignment when int != char *
Quote: > : When we did the compilers for the HEP Supercomputer (64 bit words), > : we opted for 16 bit shorts, 64 bit ints, and 64 bit longs. There is > : one more hardware supported type (half words-32 bits). Avoiding things... > Why not have int be 32 bits? That fits the requirement that > length char<=short<=int<=long. Not a comment, just a question...
Because "int" is supposed to be a convenient size. The convenient size for us is 64 bits. Since the largest number of variables are type "int" you want to use something pretty efficient (like the word size). By they way, you assumption that type "char" has some guaranteed relationship to any of the integer types is wrong, although anyone who has "char"s that aren't exactly eight bits is likely to cause many applications to die. -Ron
|
Thu, 17 Dec 1992 15:25:00 GMT |
|
 |
William E. Davidsen #14 / 27
|
 pointer alignment when int != char *
Quote:
>>Why not have int be 32 bits? That fits the requirement that >>length char<=short<=int<=long. Not a comment, just a question... >There are two main considerations for the correct size to be used for (int) >when implementing C on a new system: >1. (int) objects should be accessible quickly. On a word-addressed >architecture, this argues for making them full words.
[ I thought you mentioned that the 32 bit size was hardware supported. On many machines the short math is faster than long (ie. vax, 68000). ] Quote: >2. (int)s must be usable for indexing arrays. Depending on the address >space, one may have to either impose an artificial limit on array sizes >or else make (int)s longer than they might have been. For example, on
[ The 32 bit size allows an acceptable range as a subscript, although at some point 4GB won't be enough, most of the problems using big memory are also using multiple arrays less than 2GB. ] Quote: >I understand from hearsay that the IBM PC world (actually the Intel 8086 >world) ran against this very problem, and instead of making a single sane >choice they ended up proliferating a variety of incompatible sets of >choices (hilariously called "models"). One hopes that a lesson was learned, >but I doubt it.
That's the point I was making in my posting... the problems occur when the int won't hold an address, and then mainly because some <deleted> is playing fast & loose with bit fidling in pointers or some such. The major problems with "models" would go away if someone made the large model int the same length as the large model pointer. I've been fighting with this in pathalias, trying to get it to run on an 80*86 machine, and finding that (a) it does all its own memory allocation, and (b) it uses ints to hold addresses while doing it. This kind of non-portable code will fail on machines which are not byte addressed, and which use a pointer which looks like a word address and character offset. X3J11 covered this very well, pointers are not forced to be the size of int, they are not even the size of each other! Code written for large model 80*86 will almost always run on any other machine, assuming that it doesn't use calls to the hardware, etc. --
{chinet | philabs | sesimo}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
|
Thu, 17 Dec 1992 13:00:00 GMT |
|
|
Page 1 of 2
|
[ 27 post ] |
|
Go to page:
[1]
[2] |
|