|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
How many C compilers provide extensions which allow for a standard
implementation of the following hack? __________________________________________________ __________________ #include <stdio.h> typedef union aligner_types_u aligner_types; typedef struct aligner_offset_s aligner_offset; union aligner_types_u { char char_; short s_l; int i_; long l_; double d_; long double ld_; float f_; void *p_; char (*fp0_) (char); long double (*fp1_) (char, long double); union aligner_types* uap_; /* long long ll_; */ /* [...] */ }; struct aligner_offset_s { char offset; aligner_types types; }; #define ALIGN_MAX ( \ sizeof(aligner_offset) > sizeof(aligner_types) \ ? sizeof(aligner_offset) - sizeof(aligner_types) \ : sizeof(aligner_types) \ ) int main() { printf("ALIGN_MAX == %d\n\nhit enter to exit...\n", ALIGN_MAX); getchar(); return 0; } __________________________________________________ __________________ Thanks... BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types) alone is not sufficient... How many people are running platforms where (ALIGN_MAX == 8) is true? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
"Chris Thomasson" <cristom@comcast.net> wrote in message
news:5umdnWjfo9PPQrrVnZ2dnUVZ_rLinZ2d@comcast.com. .. > How many C compilers provide extensions which allow for a standard > implementation of the following hack? [...] Standard in the sense of being portable within the various versions of a given vendors C compiler... :^o |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> How many C compilers provide extensions which allow for a standard > implementation of the following hack? > __________________________________________________ __________________ > #include <stdio.h> > > > typedef union aligner_types_u aligner_types; > typedef struct aligner_offset_s aligner_offset; > > > union aligner_types_u { > char char_; > short s_l; > int i_; > long l_; > double d_; > long double ld_; > float f_; > void *p_; > char (*fp0_) (char); > long double (*fp1_) (char, long double); > union aligner_types* uap_; > /* long long ll_; */ > /* [...] */ > }; > > > struct aligner_offset_s { > char offset; > aligner_types types; > }; > > > #define ALIGN_MAX ( \ > sizeof(aligner_offset) > sizeof(aligner_types) \ > ? sizeof(aligner_offset) - sizeof(aligner_types) \ > : sizeof(aligner_types) \ > ) > > > int main() { > printf("ALIGN_MAX == %d\n\nhit enter to exit...\n", ALIGN_MAX); > getchar(); > return 0; > } > > __________________________________________________ __________________ > > > > Thanks... > > > > BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types) > alone is not sufficient... How many people are running platforms where > (ALIGN_MAX == 8) is true? Observation #1: It is impossible that the "else" branch of ALIGN_MAX' expansion will be evaluated, so you might as well just put `42' there. Observation #2: ALIGN_MAX computes the number of bytes in the struct, minus one for the `char' element, minus the number of padding bytes before the union, minus the number of padding bytes *after* the union. I've never seen a compiler where that final term would be non-zero, but ... Observation #3: On some platforms the program will say "ALIGN_MAX == 0", because that's one of the likely outcomes of the undefined behavior in the printf() call. Observation #4: I'm not entirely sure, but I think the "extension" you seek is the offsetof macro in <stddef.h>. -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com... > Chris Thomasson wrote: >> How many C compilers provide extensions which allow for a standard >> implementation of the following hack? >> __________________________________________________ __________________ [...] >> __________________________________________________ __________________ [...] >> BTW, the ALIGN_MAX macro is needed because using a sizeof(aligner_types) >> alone is not sufficient... How many people are running platforms where >> (ALIGN_MAX == 8) is true? > > Observation #1: It is impossible that the "else" branch > of ALIGN_MAX' expansion will be evaluated, so you might as > well just put `42' there. > Observation #2: ALIGN_MAX computes the number of bytes > in the struct, minus one for the `char' element, minus the > number of padding bytes before the union, minus the number > of padding bytes *after* the union. I've never seen a > compiler where that final term would be non-zero, but ... > Observation #3: On some platforms the program will say > "ALIGN_MAX == 0", because that's one of the likely outcomes > of the undefined behavior in the printf() call. Totally agree with everything you said. As for printf, at least I should have it formatted for an unsigned integer: %u. ;^( > Observation #4: I'm not entirely sure, but I think the > "extension" you seek is the offsetof macro in <stddef.h>. You got it: __________________________________________________ _________________ #include <stdio.h> #include <stddef.h> typedef union aligner_types_u aligner_types; typedef struct aligner_offset_s aligner_offset; union aligner_types_u { char char_; short s_l; int i_; long l_; double d_; long double ld_; float f_; union aligner_types* uap_; void *p_; char (*fp0_) (char); long double (*fp1_) (char, long double); /* long long ll_; */ /* [...] */ }; struct aligner_offset_s { char offset; aligner_types types; }; #define ALIGN_MAX offsetof(aligner_offset, types) int main() { printf("ALIGN_MAX == %u\n\nhit enter to exit...\n", ALIGN_MAX); getchar(); return 0; } __________________________________________________ _________________ I am trying to come up with somewhat "portable" hack that can attempt to determine maximum alignment for integral types across a number of different compilers. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
"Chris Thomasson" <cristom@comcast.net> wrote in message
news:tf-dndgJDOpIJbXVnZ2dnUVZ_hOdnZ2d@comcast.com... > "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message > news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com... >> Chris Thomasson wrote: >>> How many C compilers provide extensions which allow for a standard >>> implementation of the following hack? >>> __________________________________________________ __________________ > [...] >>> __________________________________________________ __________________ [...] >> Observation #4: I'm not entirely sure, but I think the >> "extension" you seek is the offsetof macro in <stddef.h>. > > You got it: > __________________________________________________ _________________ [...] > __________________________________________________ _________________ > I am trying to come up with somewhat "portable" hack that can attempt to > determine maximum alignment for integral types across a number of > different compilers. I have been successfully using the previous method in several general-purpose memory allocators. However, I wanted to see if there is a better way; offsetof works fine. BTW, does anybody know why there is not something like ALIGN_MAX in <limits.h> already? |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote... >> Chris Thomasson wrote: >> [... printf with "%d" for a size_t ...] >> Observation #3: On some platforms the program will say >> "ALIGN_MAX == 0", because that's one of the likely outcomes >> of the undefined behavior in the printf() call. > > Totally agree with everything you said. As for printf, at least I should > have it formatted for an unsigned integer: %u. ;^( Use "%u" *and* convert the size_t value to `unsigned int'. (Or you can use "%zu" with a C99 library.) The particular misbehavior I mentioned could occur on a BigEndian system with a 64-bit size_t and a 32-bit int, where a plain "%d" or "%u" would pick up the high-order (all-zero) half of the double-wide size_t number ... >> Observation #4: I'm not entirely sure, but I think the >> "extension" you seek is the offsetof macro in <stddef.h>. > > You got it: > [...] > I am trying to come up with somewhat "portable" hack that can attempt to > determine maximum alignment for integral types across a number of > different compilers. The difficulties are in enumerating all the integer types (easy in C90, hard in C99) and in making useful manipulations of pointers-as-integers (hard in C90, easier in C99 but still not a walk in the park). For simple "flat" memory models the kind of thing you're doing is straightforward, but there's the nagging possibility that the code may find its way to a more baroque environment ... -- Eric.Sosman@sun.com |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> [... determining alignment with a struct and offsetof ...] > > I have been successfully using the previous method in several > general-purpose memory allocators. However, I wanted to see if there is > a better way; offsetof works fine. BTW, does anybody know why there is > not something like ALIGN_MAX in <limits.h> already? The Rationale doesn't say why not. My guess (and it's only a guess) is that the Committee didn't want to get too involved in specifying exactly how pointers convert to and from integers. Without knowledge of which integer bits have what significance, you can't make effective use of things like ALIGN_MAX. -- Eric.Sosman@sun.com |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
"Eric Sosman" <Eric.Sosman@sun.com> wrote in message
news:1210630927.374478@news1nwk... > Chris Thomasson wrote: >> [... determining alignment with a struct and offsetof ...] >> >> I have been successfully using the previous method in several >> general-purpose memory allocators. However, I wanted to see if there is a >> better way; offsetof works fine. BTW, does anybody know why there is not >> something like ALIGN_MAX in <limits.h> already? > > The Rationale doesn't say why not. My guess (and it's only > a guess) is that the Committee didn't want to get too involved > in specifying exactly how pointers convert to and from integers. > Without knowledge of which integer bits have what significance, > you can't make effective use of things like ALIGN_MAX. Humm, a compiler vendor already has to supply a malloc implementation which returns an address that is aligned on a sufficient boundary for all integral types; right? Well, IMVHO, the standard could mention that a vendor shall set the value of ALIGN_MAX to a sufficient boundary analogous to the non-NULL return value of malloc which can accompany the alignment of any integral type. The rational is that a vendor can likely extract ALIGN_MAX from their existing malloc implementation... Is that total crap? ;^) |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote:
> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message > > news:1210630927.374478@news1nwk... > > > Chris Thomasson wrote: > >> [... determining alignment with a struct and offsetof ...] > > >> I have been successfully using the previous method in several > >> general-purpose memory allocators. However, I wanted to see if there is a > >> better way; offsetof works fine. BTW, does anybody know why there is not > >> something like ALIGN_MAX in <limits.h> already? > > > The Rationale doesn't say why not. My guess (and it's only > > a guess) is that the Committee didn't want to get too involved > > in specifying exactly how pointers convert to and from integers. > > Without knowledge of which integer bits have what significance, > > you can't make effective use of things like ALIGN_MAX. > > Humm, a compiler vendor already has to supply a malloc implementation which > returns an address that is aligned on a sufficient boundary for all integral > types; right? Well, IMVHO, the standard could mention that a vendor shall > set the value of ALIGN_MAX to a sufficient boundary analogous to the > non-NULL return value of malloc which can accompany the alignment of any > integral type. The rational is that a vendor can likely extract ALIGN_MAX > from their existing malloc implementation... If you had ALIGN_MAX what would you do with it ? |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
In article <c2857956-f78b-47c9-97a9-a262af5535f6@r66g2000hsg.googlegroups.com>,
Spiros Bousbouras <spibou@gmail.com> wrote: >If you had ALIGN_MAX what would you do with it ? Write an allocator that returns memory adequately aligned for any object, perhaps. -- Richard -- :wq |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
Spiros Bousbouras <spibou@gmail.com> writes:
> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote: >> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message >> >> news:1210630927.374478@news1nwk... >> >> > Chris Thomasson wrote: >> >> [... determining alignment with a struct and offsetof ...] >> >> >> I have been successfully using the previous method in several >> >> general-purpose memory allocators. However, I wanted to see if there is a >> >> better way; offsetof works fine. BTW, does anybody know why there is not >> >> something like ALIGN_MAX in <limits.h> already? >> >> > The Rationale doesn't say why not. My guess (and it's only >> > a guess) is that the Committee didn't want to get too involved >> > in specifying exactly how pointers convert to and from integers. >> > Without knowledge of which integer bits have what significance, >> > you can't make effective use of things like ALIGN_MAX. >> >> Humm, a compiler vendor already has to supply a malloc implementation which >> returns an address that is aligned on a sufficient boundary for all integral >> types; right? Well, IMVHO, the standard could mention that a vendor shall >> set the value of ALIGN_MAX to a sufficient boundary analogous to the >> non-NULL return value of malloc which can accompany the alignment of any >> integral type. The rational is that a vendor can likely extract ALIGN_MAX >> from their existing malloc implementation... > > If you had ALIGN_MAX what would you do with it ? One thing I might do is write my own memory allocator. Call malloc() once to get a big chunk of memory (guaranteed to be aligned properly), then dole out properly-aligned subchunks of it in response to my_malloc() calls. Free everything at once by free()ing the big chunk. Without ALIGN_MAX, I can't think of a portable way to guarantee that the pointers returned by my_malloc are properly aligned. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> "Eric Sosman" <Eric.Sosman@sun.com> wrote in message > news:1210630927.374478@news1nwk... >> Chris Thomasson wrote: >>> [... determining alignment with a struct and offsetof ...] >>> >>> I have been successfully using the previous method in several >>> general-purpose memory allocators. However, I wanted to see if there >>> is a better way; offsetof works fine. BTW, does anybody know why >>> there is not something like ALIGN_MAX in <limits.h> already? >> >> The Rationale doesn't say why not. My guess (and it's only >> a guess) is that the Committee didn't want to get too involved >> in specifying exactly how pointers convert to and from integers. >> Without knowledge of which integer bits have what significance, >> you can't make effective use of things like ALIGN_MAX. > > Humm, a compiler vendor already has to supply a malloc implementation > which returns an address that is aligned on a sufficient boundary for > all integral types; right? Well, IMVHO, the standard could mention that > a vendor shall set the value of ALIGN_MAX to a sufficient boundary > analogous to the non-NULL return value of malloc which can accompany the > alignment of any integral type. The rational is that a vendor can likely > extract ALIGN_MAX from their existing malloc implementation... > > Is that total crap? > That depends on whether the compiler supplies its own runtime, or uses one supplied by the host environment. -- Ian Collins. |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message > news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com... >> Chris Thomasson wrote: >>> How many C compilers provide extensions which allow for a standard >>> implementation of the following hack? >>> __________________________________________________ __________________ > [...] >>> __________________________________________________ __________________ > [...] >>> BTW, the ALIGN_MAX macro is needed because using a >>> sizeof(aligner_types) alone is not sufficient... How many people are >>> running platforms where (ALIGN_MAX == 8) is true? >> >> Observation #1: It is impossible that the "else" branch >> of ALIGN_MAX' expansion will be evaluated, so you might as >> well just put `42' there. > >> Observation #2: ALIGN_MAX computes the number of bytes >> in the struct, minus one for the `char' element, minus the >> number of padding bytes before the union, minus the number >> of padding bytes *after* the union. I've never seen a >> compiler where that final term would be non-zero, but ... > >> Observation #3: On some platforms the program will say >> "ALIGN_MAX == 0", because that's one of the likely outcomes >> of the undefined behavior in the printf() call. > > Totally agree with everything you said. As for printf, at least I should > have it formatted for an unsigned integer: %u. ;^( > > > >> Observation #4: I'm not entirely sure, but I think the >> "extension" you seek is the offsetof macro in <stddef.h>. > > You got it: > __________________________________________________ _________________ > #include <stdio.h> > #include <stddef.h> > > > typedef union aligner_types_u aligner_types; > typedef struct aligner_offset_s aligner_offset; > > > union aligner_types_u { > char char_; short s_l; int i_; long l_; > double d_; long double ld_; float f_; > union aligner_types* uap_; > void *p_; char (*fp0_) (char); > long double (*fp1_) (char, long double); > /* long long ll_; */ > /* [...] */ > }; > > > struct aligner_offset_s { > char offset; > aligner_types types; > }; > > > #define ALIGN_MAX offsetof(aligner_offset, types) > > > int main() { > printf("ALIGN_MAX == %u\n\nhit enter to exit...\n", ALIGN_MAX); > getchar(); > return 0; > } > __________________________________________________ _________________ > > > > I am trying to come up with somewhat "portable" hack that can attempt to > determine maximum alignment for integral types across a number of > different compilers. > How would this code with the situation where sizeof(long long) == 8 and sizeof(long double) = 12? In that case, 16 would probably be a sensible value for ALIGN_MAX. Not easy to calculate as a compile time constant. -- Ian Collins. |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
"Ian Collins" <ian-news@hotmail.com> wrote in message
news:68s1qcF2umj15U2@mid.individual.net... > Chris Thomasson wrote: >> "Eric Sosman" <Eric.Sosman@sun.com> wrote in message >> news:1210630927.374478@news1nwk... >>> Chris Thomasson wrote: >>>> [... determining alignment with a struct and offsetof ...] >>>> >>>> I have been successfully using the previous method in several >>>> general-purpose memory allocators. However, I wanted to see if there >>>> is a better way; offsetof works fine. BTW, does anybody know why >>>> there is not something like ALIGN_MAX in <limits.h> already? >>> >>> The Rationale doesn't say why not. My guess (and it's only >>> a guess) is that the Committee didn't want to get too involved >>> in specifying exactly how pointers convert to and from integers. >>> Without knowledge of which integer bits have what significance, >>> you can't make effective use of things like ALIGN_MAX. >> >> Humm, a compiler vendor already has to supply a malloc implementation >> which returns an address that is aligned on a sufficient boundary for >> all integral types; right? Well, IMVHO, the standard could mention that >> a vendor shall set the value of ALIGN_MAX to a sufficient boundary >> analogous to the non-NULL return value of malloc which can accompany the >> alignment of any integral type. The rational is that a vendor can likely >> extract ALIGN_MAX from their existing malloc implementation... >> >> Is that total crap? >> > That depends on whether the compiler supplies its own runtime, or uses > one supplied by the host environment. Humm, good point indeed. Well, in that case, I guess the compiler can probably make use of the ALIGN_MAX definition already residing in the <limits.h> file provided by a "conforming" host environment, where conforming means provides a version of the next standard which would include ALIGN_MAX in <limits.h>)... |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
"Ian Collins" <ian-news@hotmail.com> wrote in message
news:68s2caF2umj15U3@mid.individual.net... > Chris Thomasson wrote: >> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message >> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com... >>> Chris Thomasson wrote: [...] >> __________________________________________________ _________________ >> >> I am trying to come up with somewhat "portable" hack that can attempt to >> determine maximum alignment for integral types across a number of >> different compilers. >> > How would this code with the situation where sizeof(long long) == 8 and > sizeof(long double) = 12? In that case, 16 would probably be a sensible > value for ALIGN_MAX. Not easy to calculate as a compile time constant. On GCC for 32-bit x86 windows, sizeof(double) == 8, sizeof(long double) == 12 and the offsetof version of ALIGN_MAX is 8. I think reasoning for result is that 4 is suitable alignment for long double and 8 is already compatible with boundary of 4. |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
Chris Thomasson wrote:
> "Ian Collins" <ian-news@hotmail.com> wrote in message > news:68s2caF2umj15U3@mid.individual.net... >> Chris Thomasson wrote: >>> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message >>> news:0f-dnYX0zdkuqbXVnZ2dnUVZ_qTinZ2d@comcast.com... >>>> Chris Thomasson wrote: > [...] >>> __________________________________________________ _________________ > >>> >>> I am trying to come up with somewhat "portable" hack that can attempt to >>> determine maximum alignment for integral types across a number of >>> different compilers. >>> >> How would this code with the situation where sizeof(long long) == 8 and >> sizeof(long double) = 12? In that case, 16 would probably be a sensible >> value for ALIGN_MAX. Not easy to calculate as a compile time constant. > > On GCC for 32-bit x86 windows, sizeof(double) == 8, sizeof(long double) > == 12 and the offsetof version of ALIGN_MAX is 8. I think reasoning for > result is that 4 is suitable alignment for long double and 8 is already > compatible with boundary of 4. Fair enough. I have used 16 for several "semi-portable" allocators. On each platform where these were used, the native malloc also used 16. -- Ian Collins. |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
>Spiros Bousbouras <spibou@gmail.com> writes:
>> If you had ALIGN_MAX what would you do with it ? In article <lny76fkt2w.fsf@nuthaus.mib.org> Keith Thompson <kst-u@mib.org> wrote: >One thing I might do is write my own memory allocator. ... As I have noted (several times, I think) in the past, ALIGN_MAX (or ALIGNBYTES, as we spelled it in 4.4BSD) is necessary but not sufficient. You also need something that takes an "unaligned" pointer and produces the "aligned version" of that pointer, or the offset that makes it aligned. (This need only work for byte pointers, i.e., "unsigned char *", although it is probably more convenient if it is somehow generic.) -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: gmail (figure it out) http://web.torek.net/torek/index.html |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Keith Thompson <kst-u@mib.org> writes:
> Spiros Bousbouras <spibou@gmail.com> writes: >> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote: >>> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message >>> >>> news:1210630927.374478@news1nwk... >>> >>> > Chris Thomasson wrote: >>> >> [... determining alignment with a struct and offsetof ...] >>> >>> >> I have been successfully using the previous method in several >>> >> general-purpose memory allocators. However, I wanted to see if there is a >>> >> better way; offsetof works fine. BTW, does anybody know why there is not >>> >> something like ALIGN_MAX in <limits.h> already? >>> >>> > The Rationale doesn't say why not. My guess (and it's only >>> > a guess) is that the Committee didn't want to get too involved >>> > in specifying exactly how pointers convert to and from integers. >>> > Without knowledge of which integer bits have what significance, >>> > you can't make effective use of things like ALIGN_MAX. >>> >>> Humm, a compiler vendor already has to supply a malloc implementation which >>> returns an address that is aligned on a sufficient boundary for all integral >>> types; right? Well, IMVHO, the standard could mention that a vendor shall >>> set the value of ALIGN_MAX to a sufficient boundary analogous to the >>> non-NULL return value of malloc which can accompany the alignment of any >>> integral type. The rational is that a vendor can likely extract ALIGN_MAX >>> from their existing malloc implementation... >> >> If you had ALIGN_MAX what would you do with it ? > > One thing I might do is write my own memory allocator. Call malloc() > once to get a big chunk of memory (guaranteed to be aligned properly), > then dole out properly-aligned subchunks of it in response to > my_malloc() calls. Free everything at once by free()ing the big > chunk. Without ALIGN_MAX, I can't think of a portable way to > guarantee that the pointers returned by my_malloc are properly > aligned. The suggestion seems to be that ALIGN_MAX is some arithmetic value. I can't see a way to adjust a pointer using it in any potable way. I think this is the point behind Eric's "Without knowledge of which integer bits have what significance, you can't make effective use of things like ALIGN_MAX". The standard declines to say anything about what the arithmetic value of a well-aligned pointer is. If you are assuming that the suggestion is for a function-line macro: #define ALIGN_MAX(p) that behaves like a function declared void *ALIGN_MAX(void *) which adjusts the pointer it is given, then I agree it would be possible to write an allocator. (But I would suggest the name be lower-cased to match things like offsetof and changed to sound less like a constant -- another parameter might also be required to indicate "direction"). -- Ben. |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
Ben Bacarisse wrote:
> > The suggestion seems to be that ALIGN_MAX is some arithmetic value. I > can't see a way to adjust a pointer using it in any potable way. Ahh! That wets the whistle proper, that does! Barkeep, another round of Jack Daniel's Old Number (1uL << ALIGN_BITS)-1 for these good people, if you please. -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
news:877idz81nm.fsf@bsb.me.uk... > Keith Thompson <kst-u@mib.org> writes: > >> Spiros Bousbouras <spibou@gmail.com> writes: >>> On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.net> wrote: >>>> "Eric Sosman" <Eric.Sos...@sun.com> wrote in message >>>> >>>> news:1210630927.374478@news1nwk... >>>> >>>> > Chris Thomasson wrote: >>>> >> [... determining alignment with a struct and offsetof ...] >>>> >>>> >> I have been successfully using the previous method in several >>>> >> general-purpose memory allocators. [...] >>>> >>>> > The Rationale doesn't say why not. My guess (and it's only >>>> > a guess) is that the Committee didn't want to get too involved >>>> > in specifying exactly how pointers convert to and from integers. >>>> > Without knowledge of which integer bits have what significance, >>>> > you can't make effective use of things like ALIGN_MAX. >>>> >>>> Humm, a compiler vendor already has to supply a malloc implementation >>>> which >>>> returns an address that is aligned on a sufficient boundary for all >>>> integral >>>> types; right? [...] >>> If you had ALIGN_MAX what would you do with it ? >> >> One thing I might do is write my own memory allocator. [...] > The suggestion seems to be that ALIGN_MAX is some arithmetic value. I > can't see a way to adjust a pointer using it in any potable way. [...] I am currently using something like the following hack to align pointers on boundaries which are powers of 2: __________________________________________________ ________________ #include <stdio.h> #include <stddef.h> typedef union align_detail_types_u align_detail_types; typedef struct align_detail_offset_s align_detail_offset; union align_detail_types_u { char char_; short s_l; int i_; long l_; double d_; long double ld_; float f_; union align_types* uap_; void *p_; char (*fp0_) (char); long double (*fp1_) (char, long double); /* long long ll_; */ /* [...] */ }; struct align_detail_offset_s { char offset; align_detail_types types; }; typedef long int align_detail_intptr; #define ALIGN_MAX offsetof(align_detail_offset, types) #define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \ (((align_detail_intptr const)(mp_this)) + 1) & (-2) \ )) #define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \ (((align_detail_intptr const)(mp_this)) + \ ALIGN_POW2(mp_align, align_detail_intptr const) - 1) \ & (-ALIGN_POW2(mp_align, align_detail_intptr const)) \ )) #define ALIGN_CHECK(mp_this, mp_type, mp_align) ( \ (mp_this) == ALIGN(mp_this, mp_type, mp_align) \ ) typedef char ALIGN_DETAIL_SASSERT[ (ALIGN_MAX) && (ALIGN_CHECK(ALIGN_MAX, size_t, 2)) && (ALIGN_CHECK(ALIGN_MAX, size_t, sizeof(void*))) && (ALIGN_CHECK(ALIGN_MAX, size_t, sizeof(void* (*) (void*)))) && (sizeof(align_detail_intptr) >= sizeof(void*)) && (sizeof(align_detail_intptr) >= sizeof(void* (*) (void*))) ? 1 : -1 ]; #define L2CACHE_SIZE 128 #define BLOCK_SIZE 4096 #define SUPERBLOCK_SIZE (BLOCK_SIZE * 8) int main() { unsigned char* rawbuf[(SUPERBLOCK_SIZE * 2) - 1]; unsigned char* l2cachebuf = ALIGN(rawbuf, unsigned char*, L2CACHE_SIZE); unsigned char* pagebuf = ALIGN(rawbuf, unsigned char*, BLOCK_SIZE); unsigned char* superbuf = ALIGN(rawbuf, unsigned char*, SUPERBLOCK_SIZE); printf("(%u) == ALIGN_MAX\n(%p) == rawbuf\n\ (%p) == l2cachebuf\n(%p) == pagebuf\n(%p) == superbuf\n", (unsigned)ALIGN_MAX, (void*)rawbuf, (void*)l2cachebuf, (void*)pagebuf, (void*)superbuf); return 0; } __________________________________________________ ________________ Any suggestions on how to improve the abomination? ;^) > If you are assuming that the suggestion is for a function-line macro: > > #define ALIGN_MAX(p) > > that behaves like a function declared void *ALIGN_MAX(void *) which > adjusts the pointer it is given, then I agree it would be possible to > write an allocator. (But I would suggest the name be lower-cased to > match things like offsetof and changed to sound less like a constant > -- another parameter might also be required to indicate "direction"). That should be workable; I like it. |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
> Ben Bacarisse wrote: >> >> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I >> can't see a way to adjust a pointer using it in any potable way. > > Ahh! That wets the whistle proper, that does! *sigh* At least this one was mildly amusing. Most of my typos invert the meaning of the text. -- Ben. |
|
|
|
#22 |
|
Messages: n/a
Hébergeur: |
"Chris Thomasson" <cristom@comcast.net> writes:
> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message > news:877idz81nm.fsf@bsb.me.uk... <snip> > [...] >> The suggestion seems to be that ALIGN_MAX is some arithmetic value. I >> can't see a way to adjust a pointer using it in any po[r]table way. <snip, but permit me to correct my typo!> > > I am currently using something like the following hack to align > pointers on boundaries which are powers of 2: <snip> > typedef long int align_detail_intptr; <snip> > #define ALIGN_POW2(mp_this, mp_type) ((mp_type)( \ > (((align_detail_intptr const)(mp_this)) + 1) & (-2) \ > )) > > > #define ALIGN(mp_this, mp_type, mp_align) ((mp_type)( \ > (((align_detail_intptr const)(mp_this)) + \ > ALIGN_POW2(mp_align, align_detail_intptr const) - 1) \ > & (-ALIGN_POW2(mp_align, align_detail_intptr const)) \ > )) <snip> > Any suggestions on how to improve the abomination? > > ;^) I would document (maybe another clause in your static assert?) that long must be able to hold a pointer (I assume you can't use C99's intptr_t?). You rely on the representation of -2 and of -ALIGN_POW2(...). I'd use all unsigned types to avoid both. Other than that, I think this is the best you can do (but I am no expert on this so you may well get better advice shortly...). -- Ben. |
|
|
|
#23 |
|
Messages: n/a
Hébergeur: |
Chris Torek <nospam@torek.net> writes:
>>Spiros Bousbouras <spibou@gmail.com> writes: >>> If you had ALIGN_MAX what would you do with it ? > > In article <lny76fkt2w.fsf@nuthaus.mib.org> > Keith Thompson <kst-u@mib.org> wrote: >>One thing I might do is write my own memory allocator. ... > > As I have noted (several times, I think) in the past, ALIGN_MAX > (or ALIGNBYTES, as we spelled it in 4.4BSD) is necessary but not > sufficient. You also need something that takes an "unaligned" > pointer and produces the "aligned version" of that pointer, or the > offset that makes it aligned. (This need only work for byte > pointers, i.e., "unsigned char *", although it is probably more > convenient if it is somehow generic.) Unless, as I said, your memory allocator uses chunks allocated by malloc(). But yes, if you want to get your memory from somewhere other than malloc, you do need a way to generate an aligned pointer from an unaligned one. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |