Discussion:
AC_CHECK_ALIGNOF maximum ??
'Chris Hall'
2013-06-20 13:08:15 UTC
Permalink
I hope I am in the right place, if not please direct me !

I have found:

AC_CHECK_ALIGNOF (type, [includes = ‘AC_INCLUDES_DEFAULT’])

which is quite lovely, as far as it goes... but it does not appear to
tell me the maximum possible alignment.

Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess other
compilers do something similar...

...but I cannot help feeling that autoconf should cover this, but if
it does, I have failed to find where :-(

Am I looking in the wrong place ? Is there a standard spell for this
?

Thanks,

Chris
'Chris Hall'
2013-06-20 14:37:39 UTC
Permalink
I hope I am in the right place, if not please direct me !

I have found:

AC_CHECK_ALIGNOF (type, [includes = ‘AC_INCLUDES_DEFAULT’])

which is quite lovely, as far as it goes... but it does not appear to
tell me the maximum possible alignment.

Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess other
compilers do something similar...

...but I cannot help feeling that autoconf should cover this, but if
it does, I have failed to find where :-(

Am I looking in the wrong place ? Is there a standard spell for this
?

Thanks,

Chris
Eric Blake
2013-12-04 17:43:06 UTC
Permalink
Post by 'Chris Hall'
I hope I am in the right place, if not please direct me !
Just now noticing this mail, and that no one ever seemed to reply.
Post by 'Chris Hall'
AC_CHECK_ALIGNOF (type, [includes = ‘AC_INCLUDES_DEFAULT’])
which is quite lovely, as far as it goes... but it does not appear to
tell me the maximum possible alignment.
What are you expecting to do with the biggest alignment, anyways? The
most you can portably do is determine the alignment of the types you
plan on using ('long long', 'long double', or if you probe for extension
types such as __int128_t and then check the alignment of that).
Post by 'Chris Hall'
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess other
compilers do something similar...
...but I cannot help feeling that autoconf should cover this, but if
it does, I have failed to find where :-(
Without a good use case for what you expect to do with it that you
cannot already determine by checking the alignments of the biggest types
your code uses, I'm not sure that autoconf needs an extra macro.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Nick Bowler
2013-12-04 18:24:05 UTC
Permalink
Post by Eric Blake
Post by 'Chris Hall'
I hope I am in the right place, if not please direct me !
Just now noticing this mail, and that no one ever seemed to reply.
It appears that this question was double posted, as there were
followups in another thread:

http://thread.gmane.org/gmane.comp.sysutils.autoconf.general/15232

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
'Chris Hall'
2013-12-05 01:26:01 UTC
Permalink
Post by Eric Blake
What are you expecting to do with the biggest alignment, anyways?
Arrange for memory to be allocated such that, just like malloc(), one can know that it is suitably aligned for all eventualities.
Post by Eric Blake
The most you can portably do is determine the alignment of the
types you plan on using ('long long', 'long double', or if you
probe for extension types such as __int128_t and then check
the alignment of that).
Which strikes me a deeply un-portable... how do I tell from machine to machine whether 'long long' is bigger or smaller than 'long double' or any other type ?

Also, what I had in mind was some general purpose (library-like) code which has not a clue what types its client code may use.... and if it starts making assumptions, something, somewhere, sometime, is going to break horribly.

...
Post by Eric Blake
Without a good use case for what you expect to do with it that you
cannot already determine by checking the alignments of the biggest
types your code uses, I'm not sure that autoconf needs an extra
macro.
As above... I don't see how (a) I can tell for any given machine which is the biggest of any type the code currently uses -- other than by enumerating all the types it currently uses... but the "library" code I was working on, cannot possibly know what types its clients use, and enumerating all currently known types on any system I might have access to is an horrible hostage to (a) systems I don't have access to, (b) future systems, (c) new uses of the "library" which do not realise the limitations and use a type with an unsupported alignment requirement.

Since malloc() claims to be able to allocate to a maximum alignment boundary, this information is clearly not a state secret.

It does not seem unreasonable to me for a tool which is intended to aid portability -- so deal with local system properties -- to provide this small piece of local system knowledge.

Thanks,

Chris

Bob Friesenhahn
2013-06-20 14:19:01 UTC
Permalink
Post by 'Chris Hall'
I hope I am in the right place, if not please direct me !
AC_CHECK_ALIGNOF (type, [includes = ?AC_INCLUDES_DEFAULT?])
which is quite lovely, as far as it goes... but it does not appear to
tell me the maximum possible alignment.
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess other
compilers do something similar...
...but I cannot help feeling that autoconf should cover this, but if
it does, I have failed to find where :-(
How would Autoconf portably test for this and for what purpose would
you use this information for?

Compile-time estimation of biggest alignment seems risky to me if it
is used for any serious purpose. If all of the software in the
running application was not compiled with the same flags, then the
compiled-in value may be wrong.

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
'Chris Hall'
2013-06-20 15:12:51 UTC
Permalink
...
Post by Bob Friesenhahn
Post by 'Chris Hall'
AC_CHECK_ALIGNOF (type, [includes = ?AC_INCLUDES_DEFAULT?])
which is quite lovely, as far as it goes... but it does not appear
to tell me the maximum possible alignment.
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess
other compilers do something similar...
...but I cannot help feeling that autoconf should cover this, but
if it does, I have failed to find where :-(
How would Autoconf portably test for this
I have no idea. Correct me if I am wrong: but I thought Autoconf was
there to save humble journeymen like me from having to know that sort
of thing ?
Post by Bob Friesenhahn
and for what purpose would you use this information for?
Specifically... I want to allocate lumps of memory with some red tape
in front to be followed by the "body" of the allocation. That body
needs to be aligned, as if by malloc, to the maximum alignment.

For completeness, given the sizeof() the body I wish to align to
sizeof() % maximum alignment.

With C11 I could use the alignof() spell to do something more precise.
And I guess I could Autoconf my way to discovering if __alignof__() or
equivalent whizzy-ness is available.

You know and I know that 16 is probably an excellent guess that will
be true for the foreseeable... but that's hardly satisfactory !
Post by Bob Friesenhahn
Compile-time estimation of biggest alignment seems risky to me if it
is used for any serious purpose. If all of the software in the
running application was not compiled with the same flags, then the
compiled-in value may be wrong.
AFAICS any disagreement about any alignment is a recipe for tears
(before, after and during bedtime). Why should the maximum alignment
be any different ?

Thanks,

Chris
Nick Bowler
2013-06-20 15:27:41 UTC
Permalink
Post by 'Chris Hall'
...
Post by Bob Friesenhahn
Post by 'Chris Hall'
AC_CHECK_ALIGNOF (type, [includes = ?AC_INCLUDES_DEFAULT?])
which is quite lovely, as far as it goes... but it does not appear
to tell me the maximum possible alignment.
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess
other compilers do something similar...
[...]
Post by 'Chris Hall'
Post by Bob Friesenhahn
and for what purpose would you use this information for?
Specifically... I want to allocate lumps of memory with some red tape
in front to be followed by the "body" of the allocation. That body
needs to be aligned, as if by malloc, to the maximum alignment.
For completeness, given the sizeof() the body I wish to align to
sizeof() % maximum alignment.
With C11 I could use the alignof() spell to do something more precise.
And I guess I could Autoconf my way to discovering if __alignof__() or
equivalent whizzy-ness is available.
C11 also provides max_align_t, which is *probably* what you are
looking for but obviously isn't available everywhere. Anyway, on
older implementations without max_align_t, the following type is
probably a "good enough" substitute for it:

union {
char a;
short b;
int c;
long d;
long long e;
float f;
double g;
long double h;
void *i;
}

You could use AC_CHECK_TYPE to test for max_align_t, then use
AC_CHECK_ALIGNOF on the above monster if it is not available.

You may also want to test for long long availability before
including it in the union...

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Russ Allbery
2013-06-20 17:51:24 UTC
Permalink
C11 also provides max_align_t, which is *probably* what you are looking
for but obviously isn't available everywhere. Anyway, on older
implementations without max_align_t, the following type is probably a
union {
char a;
short b;
int c;
long d;
long long e;
float f;
double g;
long double h;
void *i;
}
I would add a function pointer, but yes.
You could use AC_CHECK_TYPE to test for max_align_t, then use
AC_CHECK_ALIGNOF on the above monster if it is not available.
You may also want to test for long long availability before
including it in the union...
And long double, which IIRC is more of a portability issue than long long.
--
Russ Allbery (***@stanford.edu) <http://www.eyrie.org/~eagle/>
Nick Bowler
2013-06-20 18:06:24 UTC
Permalink
Post by Russ Allbery
C11 also provides max_align_t, which is *probably* what you are looking
for but obviously isn't available everywhere. Anyway, on older
implementations without max_align_t, the following type is probably a
union {
char a;
short b;
int c;
long d;
long long e;
float f;
double g;
long double h;
void *i;
}
I would add a function pointer, but yes.
Good idea.
Post by Russ Allbery
You could use AC_CHECK_TYPE to test for max_align_t, then use
AC_CHECK_ALIGNOF on the above monster if it is not available.
You may also want to test for long long availability before
including it in the union...
And long double, which IIRC is more of a portability issue than long long.
FWIW, the autoconf manual has the following to say in §5.9.1 "Particular
Type Checks"[1]:

[AC_TYPE_LONG_DOUBLE] is obsolescent, as current C compilers support
long double. New programs need not use this macro.

[1] https://gnu.org/software/autoconf/manual/autoconf.html#Particular-Types

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
'Chris Hall'
2013-06-20 18:53:16 UTC
Permalink
Post by Nick Bowler
Post by Russ Allbery
Post by Nick Bowler
C11 also provides max_align_t, which is *probably* what you are
looking for but obviously isn't available everywhere. Anyway,
on older implementations without max_align_t, the following
union {
char a;
short b;
int c;
long d;
long long e;
float f;
double g;
long double h;
void *i;
}
I would add a function pointer, but yes.
Good idea.
Hmmm. Up to a point...

...I confess this approach makes me feel more than a little queasy. I
checked the C99 standard and the above appears to cover all the types
mentioned in 6.2.5... except for _Bool (!). I note that the _Complex
types are defined to have the same alignment as the corresponding
floats. Similarly unsigned integers are defined to align the same as
the corresponding signed ones. There's wchar_t, size_t, intptr_t, ...
which I suppose one is justified in supposing are the same as one of
the ordinary integers. But then there are the "implementation defined
extended integer types"... which aren't on the list, of course --
uint256_t, anybody ? (I cannot spot anything in the standard which
says that long long is definitely bigger than long, or that it
definitely has a larger alignment... similarly long double etc...
otherwise the list could be shortened somewhat.)

...I cannot help feeling that this would be wonderfully portable,
except where it wasn't -- and in the second of these cases you'd be in
it up to your neck, without warning.

Actually, for what I am trying to do, I have decided to fake
alignof(). It takes a bit of dicking-about, but it occurred to me
that alignof(foo_t) may be constructed as offsetof(struct { char x;
foo_t q; }, q)... Sadly gcc throws an unhelpful (in this case)
warning... which requires some scrubbing around :-(

Thanks,

Chris
Nick Bowler
2013-06-20 20:45:01 UTC
Permalink
Post by 'Chris Hall'
Post by Nick Bowler
Post by Russ Allbery
Post by Nick Bowler
C11 also provides max_align_t, which is *probably* what you are
looking for but obviously isn't available everywhere. Anyway,
on older implementations without max_align_t, the following
union {
char a;
short b;
int c;
long d;
long long e;
float f;
double g;
long double h;
void *i;
}
I would add a function pointer, but yes.
Good idea.
Hmmm. Up to a point...
...I confess this approach makes me feel more than a little queasy. I
checked the C99 standard and the above appears to cover all the types
mentioned in 6.2.5... except for _Bool (!).
Indeed, _Bool is reasonable to add as well (after checking for its
existence).
Post by 'Chris Hall'
I note that the _Complex types are defined to have the same alignment
as the corresponding floats. Similarly unsigned integers are defined
to align the same as the corresponding signed ones. There's wchar_t,
size_t, intptr_t, ... which I suppose one is justified in supposing
are the same as one of the ordinary integers.
I would only add the extra types if you actually encounter an
implementation where it matters. Feel free to add an intmax_t
member to the union as well (after checking for its existence).
Post by 'Chris Hall'
But then there are the "implementation defined extended integer
types"... which aren't on the list, of course -- uint256_t, anybody ?
(I cannot spot anything in the standard which says that long long is
definitely bigger than long, or that it definitely has a larger
alignment... similarly long double etc... otherwise the list could be
shortened somewhat.)
A few points to consider:

1) This union was suggested as a replacement for max_align_t on
implementations which do not provide it. Future implementations
will provide max_align_t, so going forward you won't depend on the
union.

2) Larger integer types are probably not going to have stricter
alignment requirements than "long long" on current processors.

3) Don't let the perfect be the enemy of the good enough.
Post by 'Chris Hall'
...I cannot help feeling that this would be wonderfully portable,
except where it wasn't -- and in the second of these cases you'd be in
it up to your neck, without warning.
Unfortunately, it's likely the best you can do without something like
max_align_t, or __BIGGEST_ALIGNMENT__, or whatever.
Post by 'Chris Hall'
Actually, for what I am trying to do, I have decided to fake
alignof(). It takes a bit of dicking-about, but it occurred to me
that alignof(foo_t) may be constructed as offsetof(struct { char x;
foo_t q; }, q)... Sadly gcc throws an unhelpful (in this case)
warning... which requires some scrubbing around :-(
This pattern is essentially the same as how AC_CHECK_ALIGNOF actually
works. There is also an alignof module in Gnulib which may be of
interest to you.

But I'm not sure this (by itself) helps you, since you'd still need a
suitable definition of foo_t.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
'Chris Hall'
2013-06-21 08:36:57 UTC
Permalink
Nick Bowler wrote (on Thu 20-Jun-2013 at 21:45 +0100):
....
Post by Nick Bowler
I would only add the extra types if you actually encounter an
implementation where it matters. Feel free to add an intmax_t
member to the union as well (after checking for its existence).
The problem I have is that where "it matters" the program would
happily build, but fall over in obscure ways at run-time on some
distant system which happens to be running something out of the
ordinary.

...
Post by Nick Bowler
3) Don't let the perfect be the enemy of the good enough.
Something which failed at build-time would indeed be "good enough".

...
Post by Nick Bowler
Unfortunately, it's likely the best you can do without something
like max_align_t, or __BIGGEST_ALIGNMENT__, or whatever.
What I was hoping for was help from Autoconf in identifying where one
of these mechanisms was available. If many/most compilers provide,
say, __BIGGEST_ALIGNMENT__ but some have a different name for it, then
that seems to me something that Autoconf could/should help with.

Where no such mechanism is available, then a compile time error would
tell everybody that some extra work is required... perhaps a -Dbar for
building in some (obscure) environment.
Post by Nick Bowler
Post by 'Chris Hall'
Actually, for what I am trying to do, I have decided to fake
alignof(). It takes a bit of dicking-about, but it occurred to me
that alignof(foo_t) may be constructed as offsetof(struct { char
x; foo_t q; }, q)... Sadly gcc throws an unhelpful (in this case)
warning... which requires some scrubbing around :-(
This pattern is essentially the same as how AC_CHECK_ALIGNOF
actually works. There is also an alignof module in Gnulib
which may be of interest to you.
Thanks. Happy to see the trick is generally agreed to work :-) It
throws an "anonymous struct declared inside parameter list [enabled by
default]" warning, though :-(
Post by Nick Bowler
But I'm not sure this (by itself) helps you, since you'd still need
a suitable definition of foo_t.
I'm allocating memory for various types en masse. So I malloc enough
for some general red-tape followed by a bunch of items of foo_t -- for
various foo_t. My first thought was to ensure that the red-tape was
__BIGGEST_ALIGNMENT__ aligned. My second thought was to align
sizeof(foo_t) % __BIGGEST_ALIGNMENT__ where that isn't zero. My third
thought was alignof(foo_t).

Thanks,

Chris
Paul Eggert
2013-06-21 17:42:41 UTC
Permalink
Post by 'Chris Hall'
What I was hoping for was help from Autoconf in identifying where one
of these mechanisms was available.
This sounds like a good idea, either in Autoconf or gnulib.
I hope someone can take the time to implement it.
Bob Friesenhahn
2013-06-20 15:31:41 UTC
Permalink
Post by 'Chris Hall'
Post by Bob Friesenhahn
Post by 'Chris Hall'
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess
other compilers do something similar...
...but I cannot help feeling that autoconf should cover this, but
if it does, I have failed to find where :-(
How would Autoconf portably test for this
I have no idea. Correct me if I am wrong: but I thought Autoconf was
there to save humble journeymen like me from having to know that sort
of thing ?
Autoconf figures things out by running the compiler and linker in a
portable way. It does not usually want to run the compiled test
program because that does not work for cross-compilation. There needs
to be a way to discover the desired alignment by compiling code.
Post by 'Chris Hall'
Post by Bob Friesenhahn
and for what purpose would you use this information for?
Specifically... I want to allocate lumps of memory with some red tape
in front to be followed by the "body" of the allocation. That body
needs to be aligned, as if by malloc, to the maximum alignment.
For completeness, given the sizeof() the body I wish to align to
sizeof() % maximum alignment.
With C11 I could use the alignof() spell to do something more precise.
And I guess I could Autoconf my way to discovering if __alignof__() or
equivalent whizzy-ness is available.
You know and I know that 16 is probably an excellent guess that will
be true for the foreseeable... but that's hardly satisfactory !
I am not so sure. Are you talking about the alignment of a large type
like 'double', 'long double', a 128-bit integer on PowerPC, the
alignment required by SSE2 instructions, or the alignment required by
some AVX instructions (see
http://software.intel.com/en-us/forums/topic/299644)?
Post by 'Chris Hall'
Post by Bob Friesenhahn
Compile-time estimation of biggest alignment seems risky to me if it
is used for any serious purpose. If all of the software in the
running application was not compiled with the same flags, then the
compiled-in value may be wrong.
AFAICS any disagreement about any alignment is a recipe for tears
(before, after and during bedtime). Why should the maximum alignment
be any different ?
Depending on what you mean by 'maximum alignment', the answer could be
different depending on compiler options and the target instruction
set.

Autoconf usually creates a configuration header file which is used by
all of the code in the project. If some parts of an application are
built with different flags, they might still work in the application
but object code may require different maximum alignment.

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Harlan Stenn
2013-06-20 18:11:03 UTC
Permalink
Post by Bob Friesenhahn
Post by 'Chris Hall'
Post by Bob Friesenhahn
Post by 'Chris Hall'
Of course gcc gives __BIGGEST_ALIGNMENT__ for this. And I guess
other compilers do something similar...
...but I cannot help feeling that autoconf should cover this, but
if it does, I have failed to find where :-(
How would Autoconf portably test for this
I have no idea. Correct me if I am wrong: but I thought Autoconf was
there to save humble journeymen like me from having to know that sort
of thing ?
Autoconf figures things out by running the compiler and linker in a
portable way. It does not usually want to run the compiled test
program because that does not work for cross-compilation. There needs
to be a way to discover the desired alignment by compiling code.
But that's not really an issue.

The goal here seems to be "make it work easily for somebody who wants to
install the package to a ported system". There are several autoconf
tests where one must have additional knowledge for cross-compile cases,
and in that case whoever is responsible for doing that port should be
updating the configure.ac file with the information needed by the
target.

H
Loading...