470,848 Members | 1,290 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,848 developers. It's quick & easy.

standard memory allocator alignment issue...

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?

Jun 27 '08 #1
31 1491
"Chris Thomasson" <cr*****@comcast.netwrote in message
news:5u******************************@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

Jun 27 '08 #2
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
es*****@ieee-dot-org.invalid
Jun 27 '08 #3
"Eric Sosman" <es*****@ieee-dot-org.invalidwrote in message
news:0f******************************@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.

Jun 27 '08 #4
"Chris Thomasson" <cr*****@comcast.netwrote in message
news:tf******************************@comcast.com. ..
"Eric Sosman" <es*****@ieee-dot-org.invalidwrote in message
news:0f******************************@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.halready?

Jun 27 '08 #5
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.halready?
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.

--
Er*********@sun.com
Jun 27 '08 #6
"Eric Sosman" <Er*********@sun.comwrote 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.halready?

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?

;^)

Jun 27 '08 #7
On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.netwrote:
"Eric Sosman" <Eric.Sos...@sun.comwrote 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.halready?
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 ?

Jun 27 '08 #8
In article <c2**********************************@r66g2000hsg. googlegroups.com>,
Spiros Bousbouras <sp****@gmail.comwrote:
>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
Jun 27 '08 #9
Spiros Bousbouras <sp****@gmail.comwrites:
On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.netwrote:
>"Eric Sosman" <Eric.Sos...@sun.comwrote 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.halready?
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) ks***@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"
Jun 27 '08 #10
Chris Thomasson wrote:
"Eric Sosman" <Er*********@sun.comwrote 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.halready?

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.
Jun 27 '08 #11
Chris Thomasson wrote:
"Eric Sosman" <es*****@ieee-dot-org.invalidwrote in message
news:0f******************************@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.
Jun 27 '08 #12
"Ian Collins" <ia******@hotmail.comwrote in message
news:68*************@mid.individual.net...
Chris Thomasson wrote:
>"Eric Sosman" <Er*********@sun.comwrote 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.halready?

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.hfile provided by a "conforming" host environment, where
conforming means provides a version of the next standard which would include
ALIGN_MAX in <limits.h>)...

Jun 27 '08 #13
"Ian Collins" <ia******@hotmail.comwrote in message
news:68*************@mid.individual.net...
Chris Thomasson wrote:
>"Eric Sosman" <es*****@ieee-dot-org.invalidwrote in message
news:0f******************************@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.

Jun 27 '08 #14
Chris Thomasson wrote:
"Ian Collins" <ia******@hotmail.comwrote in message
news:68*************@mid.individual.net...
>Chris Thomasson wrote:
>>"Eric Sosman" <es*****@ieee-dot-org.invalidwrote in message
news:0f******************************@comcast.co m...
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.
Jun 27 '08 #15
>Spiros Bousbouras <sp****@gmail.comwrites:
>If you had ALIGN_MAX what would you do with it ?
In article <ln************@nuthaus.mib.org>
Keith Thompson <ks***@mib.orgwrote:
>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 (4039.22'N, 11150.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Jun 27 '08 #16
Keith Thompson <ks***@mib.orgwrites:
Spiros Bousbouras <sp****@gmail.comwrites:
>On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.netwrote:
>>"Eric Sosman" <Eric.Sos...@sun.comwrote 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.halready?

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.
Jun 27 '08 #17
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
es*****@ieee-dot-org.invalid
Jun 27 '08 #18
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
Keith Thompson <ks***@mib.orgwrites:
>Spiros Bousbouras <sp****@gmail.comwrites:
>>On 12 May, 23:41, "Chris Thomasson" <cris...@comcast.netwrote:
"Eric Sosman" <Eric.Sos...@sun.comwrote 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.

Jun 27 '08 #19
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
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.
Jun 27 '08 #20
"Chris Thomasson" <cr*****@comcast.netwrites:
"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@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.
Jun 27 '08 #21
Chris Torek <no****@torek.netwrites:
>>Spiros Bousbouras <sp****@gmail.comwrites:
>>If you had ALIGN_MAX what would you do with it ?

In article <ln************@nuthaus.mib.org>
Keith Thompson <ks***@mib.orgwrote:
>>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) ks***@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"
Jun 27 '08 #22
Ben Bacarisse <be********@bsb.me.ukwrites:
Keith Thompson <ks***@mib.orgwrites:
>Spiros Bousbouras <sp****@gmail.comwrites:
[...]
>>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.
Agreed. An ALIGN_MAX constant (which might typically be 8 on modern
systems) is useful only if you start with an address that you already
know is adequately aligned -- which is why I started with malloc().
It's not enough to let you write a portable malloc()-like function
from scratch.
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").
Or you could have, say an alignment_offset(p) macro which, given a
char* value, gives you a small integer value you can add to it to
yield a pointer that's guaranteed to be adequately aligned.

--
Keith Thompson (The_Other_Keith) ks***@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"
Jun 27 '08 #23
On 12 May, 23:08, Eric Sosman <Eric.Sos...@sun.comwrote:
Chris Thomasson wrote:

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)...
Isn't it actually impossible to enumerate all the integer
types in C99 ? The standard allows extended integer
types so you have no way of knowing whether on some
platform you have a "hideously long int" which has
stricter alignment requirements than every standard
type.
Jun 27 '08 #24
Spiros Bousbouras wrote:
On 12 May, 23:08, Eric Sosman <Eric.Sos...@sun.comwrote:
>Chris Thomasson wrote:
>>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)...

Isn't it actually impossible to enumerate all the integer
types in C99 ? The standard allows extended integer
types so you have no way of knowing whether on some
platform you have a "hideously long int" which has
stricter alignment requirements than every standard
type.
Well, "impossible" is just a special case of "hard,"
right? ;-)

I'd actually written "impossible" and then I backed
off just in case Somebody Way Smarter Than Me came up with
a nifty dodge. For example, SWSTM might produce a proof
that the alignment of uintmax_t suffices for all other
integers, too. I don't know of any such proof (even if
I did, the margin of this post would probably be too narrow
to contain it) but SWSTM might come up with something, so
I ducked the issue.

--
Er*********@sun.com
Jun 27 '08 #25
Eric Sosman <Er*********@sun.comwrites:
Spiros Bousbouras wrote:
>On 12 May, 23:08, Eric Sosman <Eric.Sos...@sun.comwrote:
>>Chris Thomasson wrote:
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)...
Isn't it actually impossible to enumerate all the integer
types in C99 ? The standard allows extended integer
types so you have no way of knowing whether on some
platform you have a "hideously long int" which has
stricter alignment requirements than every standard
type.

Well, "impossible" is just a special case of "hard,"
right? ;-)

I'd actually written "impossible" and then I backed
off just in case Somebody Way Smarter Than Me came up with
a nifty dodge. For example, SWSTM might produce a proof
that the alignment of uintmax_t suffices for all other
integers, too. I don't know of any such proof (even if
I did, the margin of this post would probably be too narrow
to contain it) but SWSTM might come up with something, so
I ducked the issue.
Actually, I'm reasonably sure that uintmax_t is *not* required to have
an alignment that suffices for all other integer types.

It's even plausible that some smaller integer type might have stricter
alignment than uintmax_t. Suppose types up to 64 bits are implemented
in hardware, and each N-bit hardware type requires N-bit alignment.
Suppose uintmax_t is 128 bits, implemented in software as (the
equivalent of) an array of 4 32-bit integers, requiring only 32-bit
alignment. (Assume there's a good reason to do this rather than an
array of 2 64-bit integers).

--
Keith Thompson (The_Other_Keith) ks***@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"
Jun 27 '08 #26
On 13 May, 03:00, "Chris Thomasson" <cris...@comcast.netwrote:
>
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_; */
/* [...] */
Why are you using 2 function pointers , don't
all function pointers have the same alignment
requirements ?
>
};

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) \
))
Why are you casting to const ?
>
#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;

}
Jun 27 '08 #27
Eric Sosman wrote:
>
.... snip ...
>
I'd actually written "impossible" and then I backed
off just in case Somebody Way Smarter Than Me came up with
a nifty dodge. For example, SWSTM might produce a proof
that the alignment of uintmax_t suffices for all other
integers, too. I don't know of any such proof (even if
I did, the margin of this post would probably be too narrow
to contain it) but SWSTM might come up with something, so
I ducked the issue.
I always start to put the proof of my elegant algorithms in the
margin of my notebooks, and always discover that there is
insufficient room to complete it. So I so annotate it. What's the
problem?

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
** Posted from http://www.teranews.com **
Jun 27 '08 #28
CBFalconer wrote:
Eric Sosman wrote:
... snip ...
> I'd actually written "impossible" and then I backed
off just in case Somebody Way Smarter Than Me came up with
a nifty dodge. For example, SWSTM might produce a proof
that the alignment of uintmax_t suffices for all other
integers, too. I don't know of any such proof (even if
I did, the margin of this post would probably be too narrow
to contain it) but SWSTM might come up with something, so
I ducked the issue.

I always start to put the proof of my elegant algorithms in the
margin of my notebooks, and always discover that there is
insufficient room to complete it. So I so annotate it. What's the
problem?
<off-topic>

My fear is that if I put an incomplete proof in the margin
it will turn out to be my Last Theorem -- and I DON' WANNA DIE!

</off-topic>
Jun 27 '08 #29
Eric Sosman said:

<snip>
>
My fear is that if I put an incomplete proof in the margin
it will turn out to be my Last Theorem -- and I DON' WANNA DIE!
G H Hardy was once obliged to take a boat trip about which he was feeling
rather nervous. So he sent a postcard to a mathematician friend, claiming
to have proved the Riemann Hypothesis and promising details upon his safe
return. Hardy (an ardent atheist) reasoned that God wouldn't allow him to
gain eternal fame in such a deceitful way, and would therefore ensure the
safety of the vessel.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #30
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
Ben Bacarisse <be********@bsb.me.ukwrites:
>Keith Thompson <ks***@mib.orgwrites:
>>Spiros Bousbouras <sp****@gmail.comwrites:
[...]
>>>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.

Agreed. An ALIGN_MAX constant (which might typically be 8 on modern
systems) is useful only if you start with an address that you already
know is adequately aligned -- which is why I started with malloc().
It's not enough to let you write a portable malloc()-like function
from scratch.
[...]

Exactly Right! However, that limitation is fairly trivial. You cannot create
a standard malloc with C. However, with something like ALIGN_MAX, one could
certainly create a 100% standard general-purpose custom allocation scheme
directly on top of malloc. Perhaps, one could create something that is
faster than malloc, and completely standard, for their specific problem
domains. Your correct in that ALIGN_MAX and the standard malloc call would
go hand-in-hand... Am I misrepresenting you here?

AFAICT, using malloc to retrieve a standard base, and ALIGN_MAX to round
offset calculations off to would work perfectly... For instance, a 100%
standard region-allocator can look like:

<pseudo-code sketch>
__________________________________________________ _______________
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>

#define REGION_HEAPSIZE 8192

struct region {
char* heap; /* init with `malloc(REGION_HEAPSIZE);' */
size_t offset; /* init to zero */
};

static void* region_alloc(
struct region* const _this,
size_t size
) {
size_t const offset = _this->offset;
size = ROUND_UP(size, ALIGN_MAX);
if (offset + size REGION_HEAPSIZE) {
return NULL;
}
_this->offset = offset + size;
return _this->heap + offset;
}

static void region_reset(
struct region* const _this
) {
_this->offset = 0;
}
__________________________________________________ _______________

This could be 100% standard with ALIGN_MAX... What do you think? Is that
Kosher?

Jun 27 '08 #31

"Chris Thomasson" <cr*****@comcast.netwrote in message
news:aZ******************************@comcast.com. ..
[...]
<pseudo-code sketch>
__________________________________________________ _______________
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>

#define REGION_HEAPSIZE 8192

struct region {
char* heap; /* init with `malloc(REGION_HEAPSIZE);' */
size_t offset; /* init to zero */
};

static void* region_alloc(
struct region* const _this,
size_t size
) {
size_t const offset = _this->offset;
size = ROUND_UP(size, ALIGN_MAX);
assert(! (size % ALIGN_MAX));

of course; just for "sanity" check! ;^)


if (offset + size REGION_HEAPSIZE) {
return NULL;
}
_this->offset = offset + size;
return _this->heap + offset;
}

static void region_reset(
struct region* const _this
) {
_this->offset = 0;
}
__________________________________________________ _______________

This could be 100% standard with ALIGN_MAX... What do you think? Is that
Kosher?
Jun 27 '08 #32

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

18 posts views Thread by Tron Thomas | last post: by
4 posts views Thread by Romeo Colacitti | last post: by
6 posts views Thread by marktxx | last post: by
22 posts views Thread by Chris Thomasson | last post: by
31 posts views Thread by Francine.Neary | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.