Next: Particular Functions, Previous: Generic Compiler Characteristics, Up: C [Contents][Index]
The following macros provide ways to find and exercise a C Compiler. There are a few constructs that ought to be avoided, but do not deserve being checked for, since they can easily be worked around.
TODO: Shunt this portability stuff elsewhere.
They tickle a bug in the HP-UX C compiler (checked on HP-UX 10.20, 11.00, and 11i). When given the following source:
#ifdef __STDC__ /\ * A comment with backslash-newlines in it. %{ %} *\ \ / char str[] = "\\ " A string with backslash-newlines in it %{ %} \\ ""; char apostrophe = '\\ \ '\ '; #endif
the compiler incorrectly fails with the diagnostics “Non-terminating comment at end of file” and “Missing ‘#endif’ at end of file.” Removing the lines with solitary backslashes solves the problem.
Some compilers, such as HP’s, report names of files being compiled when given more than one file operand. For instance:
$ cc a.c b.c a.c: b.c:
This can cause problems if you observe the output of the compiler to detect failures. Invoking ‘cc -c a.c && cc -c b.c && cc -o c a.o b.o’ solves the issue.
#error
failingThe IRIX C compiler does not fail when #error is preprocessed; it
simply emits a diagnostic and continues, exiting successfully. So,
instead of an error directive like #error "Unsupported word size"
it is more portable to use an invalid directive like #Unsupported
word size
in Autoconf tests. In ordinary source code, #error
is
OK, since installers with inadequate compilers like IRIX can simply
examine these compilers’ diagnostic output.
#line
supportOn Solaris, c89
(at least Sun C 5.3 through 5.8)
diagnoses #line
directives whose line
numbers are greater than 32767. Nothing in Posix
makes this invalid. That is why Autoconf stopped issuing
#line
directives.
Determine a C compiler to use. If CC
is not already set in the
environment, check for gcc
and cc
, then for other C
compilers. Set output variable CC
to the name of the compiler
found.
This macro may, however, be invoked with an optional first argument
which, if specified, must be a blank-separated list of C compilers to
search for. This just gives the user an opportunity to specify an
alternative search list for the C compiler. For example, if you didn’t
like the default order, then you could invoke AC_PROG_CC
like
this:
AC_PROG_CC([gcc cl cc])
If necessary, add an option to output variable CC
to enable
support for ISO Standard C features with extensions. Prefer the newest
C standard that is supported. Currently the newest standard is ISO C11,
with ISO C99 and ANSI C89 (ISO C90) being the older versions.
After calling this macro you can check whether the C compiler has been
set to accept Standard C; if not, the shell variable
ac_cv_prog_cc_stdc
is set to ‘no’.
When attempting to add compiler options, prefer extended functionality
to strict conformance: the goal is to enable whatever standard features
that are available, not to check for full conformance to the standard or
to prohibit incompatible extensions. Test for C11 support by checking
for _Alignas
, _Alignof
, _Noreturn
,
_Static_assert
, UTF-8 string literals, duplicate typedef
s,
and anonymous structures and unions. Test for C99 support by checking
for _Bool
, //
comments, flexible array members,
inline
, signed and unsigned long long int
, mixed code and
declarations, named initialization of structs, restrict
,
va_copy
, varargs macros, variable declarations in for
loops, and variable length arrays. Test for C89 support by checking for
function prototypes.
If using a compiler that supports GNU C, set shell variable GCC
to
‘yes’. If output variable CFLAGS
was not already set, set
it to -g -O2 for a GNU C compiler (-O2 on systems
where the compiler does not accept -g), or -g for
other compilers. If your package does not like this default, then it is
acceptable to insert the line ‘: ${CFLAGS=""}’ after AC_INIT
and before AC_PROG_CC
to select an empty default instead.
Many Autoconf macros use a compiler, and thus call
‘AC_REQUIRE([AC_PROG_CC])’ to ensure that the compiler has been
determined before the body of the outermost AC_DEFUN
macro.
AC_PROG_CC
is therefore defined via AC_DEFUN_ONCE
to avoid
needless reexpansion (see One-Shot Macros).
If the C compiler does not accept the -c and -o options
simultaneously, define NO_MINUS_C_MINUS_O
. This macro actually
tests both the compiler found by AC_PROG_CC
, and, if different,
the first cc
in the path. The test fails if one fails. This
macro was created for GNU Make to choose the default C compilation
rule.
For the compiler compiler, this macro caches its result in the
ac_cv_prog_cc_compiler_c_o
variable.
Set output variable CPP
to a command that runs the
C preprocessor. If ‘$CC -E’ doesn’t work, /lib/cpp is used.
It is only portable to run CPP
on files with a .c
extension.
Some preprocessors don’t indicate missing include files by the error
status. For such preprocessors an internal variable is set that causes
other macros to check the standard error from the preprocessor and
consider the test failed if any warnings have been reported.
For most preprocessors, though, warnings do not cause include-file
tests to fail unless AC_PROG_CPP_WERROR
is also specified.
This acts like AC_PROG_CPP
, except it treats warnings from the
preprocessor as errors even if the preprocessor exit status indicates
success. This is useful for avoiding headers that generate mandatory
warnings, such as deprecation notices.
The following macros check for C compiler or machine architecture
features. To check for characteristics not listed here, use
AC_COMPILE_IFELSE
(see Running the Compiler) or
AC_RUN_IFELSE
(see Runtime).
Define ‘HAVE_C_BACKSLASH_A’ to 1 if the C compiler understands ‘\a’.
This macro is obsolescent, as current C compilers understand ‘\a’. New programs need not use this macro.
If words are stored with the most significant byte first (like Motorola and SPARC CPUs), execute action-if-true. If words are stored with the least significant byte first (like Intel and VAX CPUs), execute action-if-false.
This macro runs a test-case if endianness cannot be determined from the system header files. When cross-compiling, the test-case is not run but grep’ed for some magic values. action-if-unknown is executed if the latter case fails to determine the byte sex of the host system.
In some cases a single run of a compiler can generate code for multiple
architectures. This can happen, for example, when generating Mac OS X
universal binary files, which work on both PowerPC and Intel
architectures. In this case, the different variants might be for
different architectures whose endiannesses differ. If
configure
detects this, it executes action-if-universal
instead of action-if-unknown.
The default for action-if-true is to define
‘WORDS_BIGENDIAN’. The default for action-if-false is to do
nothing. The default for action-if-unknown is to
abort configure and tell the installer how to bypass this test.
And finally, the default for action-if-universal is to ensure that
‘WORDS_BIGENDIAN’ is defined if and only if a universal build is
detected and the current code is big-endian; this default works only if
autoheader
is used (see autoheader Invocation).
If you use this macro without specifying action-if-universal, you
should also use AC_CONFIG_HEADERS
; otherwise
‘WORDS_BIGENDIAN’ may be set incorrectly for Mac OS X universal
binary files.
If the C compiler does not fully support the const
keyword,
define const
to be empty. Some C compilers that do
not define __STDC__
do support const
; some compilers that
define __STDC__
do not completely support const
. Programs
can simply use const
as if every C compiler supported it; for
those that don’t, the makefile or configuration header file
defines it as empty.
Occasionally installers use a C++ compiler to compile C code, typically
because they lack a C compiler. This causes problems with const
,
because C and C++ treat const
differently. For example:
const int foo;
is valid in C but not in C++. These differences unfortunately cannot be
papered over by defining const
to be empty.
If autoconf
detects this situation, it leaves const
alone,
as this generally yields better results in practice. However, using a
C++ compiler to compile C code is not recommended or supported, and
installers who run into trouble in this area should get a C compiler
like GCC to compile their C code.
This macro caches its result in the ac_cv_c_const
variable.
This macro is obsolescent, as current C compilers support const
.
New programs need not use this macro.
If the C compiler supports C11-style generic selection using the
_Generic
keyword, define HAVE_C__GENERIC
.
If the C compiler recognizes a variant spelling for the restrict
keyword (__restrict
, __restrict__
, or _Restrict
),
then define restrict
to that; this is more likely to do the right
thing with compilers that support language variants where plain
restrict
is not a keyword. Otherwise, if the C compiler
recognizes the restrict
keyword, don’t do anything.
Otherwise, define restrict
to be empty.
Thus, programs may simply use restrict
as if every C compiler
supported it; for those that do not, the makefile
or configuration header defines it away.
Although support in C++ for the restrict
keyword is not
required, several C++ compilers do accept the keyword.
This macro works for them, too.
This macro caches ‘no’ in the ac_cv_c_restrict
variable
if restrict
is not supported, and a supported spelling otherwise.
If the C compiler does not understand the keyword volatile
,
define volatile
to be empty. Programs can simply use
volatile
as if every C compiler supported it; for those that do
not, the makefile or configuration header defines it as
empty.
If the correctness of your program depends on the semantics of
volatile
, simply defining it to be empty does, in a sense, break
your code. However, given that the compiler does not support
volatile
, you are at its mercy anyway. At least your
program compiles, when it wouldn’t before.
See Volatile Objects for more about volatile
.
In general, the volatile
keyword is a standard C feature, so
you might expect that volatile
is available only when
__STDC__
is defined. However, Ultrix 4.3’s native compiler does
support volatile, but does not define __STDC__
.
This macro is obsolescent, as current C compilers support volatile
.
New programs need not use this macro.
If the C compiler supports the keyword inline
, do nothing.
Otherwise define inline
to __inline__
or __inline
if it accepts one of those, otherwise define inline
to be empty.
If the C type char
is unsigned, define __CHAR_UNSIGNED__
,
unless the C compiler predefines it.
These days, using this macro is not necessary. The same information can be determined by this portable alternative, thus avoiding the use of preprocessor macros in the namespace reserved for the implementation.
#include <limits.h> #if CHAR_MIN == 0 # define CHAR_UNSIGNED 1 #endif
If the C preprocessor supports the stringizing operator, define
HAVE_STRINGIZE
. The stringizing operator is ‘#’ and is
found in macros such as this:
#define x(y) #y
This macro is obsolescent, as current C compilers support the stringizing operator. New programs need not use this macro.
If the C compiler supports flexible array members, define
FLEXIBLE_ARRAY_MEMBER
to nothing; otherwise define it to 1.
That way, a declaration like this:
struct s { size_t n_vals; double val[FLEXIBLE_ARRAY_MEMBER]; };
will let applications use the “struct hack” even with compilers that do not support flexible array members. To allocate and use such an object, you can use code like this:
size_t i; size_t n = compute_value_count (); struct s *p = malloc (offsetof (struct s, val) + n * sizeof (double)); p->n_vals = n; for (i = 0; i < n; i++) p->val[i] = compute_value (i);
If the C compiler does not support variable-length arrays, define the
macro __STDC_NO_VLA__
to be 1 if it is not already defined. A
variable-length array is an array of automatic storage duration whose
length is determined at run time, when the array is declared. For
backward compatibility this macro also defines HAVE_C_VARARRAYS
if the C compiler supports variable-length arrays, but this usage is
obsolescent and new programs should use __STDC_NO_VLA__
.
If the C compiler supports GNU C’s typeof
syntax either
directly or
through a different spelling of the keyword (e.g., __typeof__
),
define HAVE_TYPEOF
. If the support is available only through a
different spelling, define typeof
to that spelling.
If function prototypes are understood by the compiler (as determined by
AC_PROG_CC
), define PROTOTYPES
and __PROTOTYPES
.
Defining __PROTOTYPES
is for the benefit of
header files that cannot use macros that infringe on user name space.
This macro is obsolescent, as current C compilers support prototypes. New programs need not use this macro.
Add -traditional to output variable CC
if using a
GNU C compiler and ioctl
does not work properly without
-traditional. That usually happens when the fixed header files
have not been installed on an old system.
This macro is obsolescent, since current versions of the GNU C compiler fix the header files automatically when installed.
Next: Particular Functions, Previous: Generic Compiler Characteristics, Up: C [Contents][Index]