Next: C++ Compiler, Previous: Generic Compiler Characteristics, Up: Compilers and Preprocessors
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.
#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.
$ 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
failing#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
support#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 forgcc
andcc
, then for other C compilers. Set output variableCC
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 the C compiler does not handle function prototypes correctly by default, try to add an option to output variable
CC
to make it so. This macro tries various options that select standard-conformance modes on various systems.After calling this macro you can check whether the C compiler has been set to accept ANSI C89 (ISO C90); if not, the shell variable
ac_cv_prog_cc_c89
is set to `no'. See alsoAC_C_PROTOTYPES
below.If using the GNU C compiler, set shell variable
GCC
to `yes'. If output variableCFLAGS
was not already set, set it to -g -O2 for the GNU C compiler (-O2 on systems where GCC does not accept -g), or -g for other compilers.
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 byAC_PROG_CC
, and, if different, the firstcc
in the path. The test fails if one fails. This macro was created for GNU Make to choose the default C compilation rule.
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 runCPP
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).
If the C compiler cannot compile ISO Standard C (currently C99), try to add an option to output variable
CC
to make it work. If the compiler does not support C99, fall back to supporting ANSI C89 (ISO C90).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'.
If the C compiler is not in ANSI C89 (ISO C90) mode by default, try to add an option to output variable
CC
to make it so. This macro tries various options that select ANSI C89 on some system or another. It considers the compiler to be in ANSI C89 mode if it handles function prototypes correctly.After calling this macro you can check whether the C compiler has been set to accept ANSI C89; if not, the shell variable
ac_cv_prog_cc_c89
is set to `no'.This macro is called automatically by
AC_PROG_CC
.
If the C compiler is not in C99 mode by default, try to add an option to output variable
CC
to make it so. This macro tries various options that select C99 on some system or another. It considers the compiler to be in C99 mode if it handles_Bool
,//
comments, flexible array members,inline
, signed and unsignedlong long int
, mixed code and declarations, named initialization of structs,restrict
,va_copy
, varargs macros, variable declarations infor
loops, and variable length arrays.After calling this macro you can check whether the C compiler has been set to accept C99; if not, the shell variable
ac_cv_prog_cc_c99
is set to `no'.
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, defineconst
to be empty. Some C compilers that do not define__STDC__
do supportconst
; some compilers that define__STDC__
do not completely supportconst
. Programs can simply useconst
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++ treatconst
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 is obsolescent, as current C compilers support
const
. New programs need not use this macro.
If the C compiler recognizes a variant spelling for the
restrict
keyword (__restrict
,__restrict__
, or_Restrict
), then definerestrict
to that; this is more likely to do the right thing with compilers that support language variants where plainrestrict
is not a keyword. Otherwise, if the C compiler recognizes therestrict
keyword, don't do anything. Otherwise, definerestrict
to be empty. Thus, programs may simply userestrict
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.
If the C compiler does not understand the keyword
volatile
, definevolatile
to be empty. Programs can simply usevolatile
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 supportvolatile
, you are at its mercy anyway. At least your program compiles, when it wouldn't before. See Volatile Objects, for more aboutvolatile
.In general, the
volatile
keyword is a standard C feature, so you might expect thatvolatile
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 defineinline
to__inline__
or__inline
if it accepts one of those, otherwise defineinline
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) #yThis 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 supports variable-length arrays, define
HAVE_C_VARARRAYS
. A variable-length array is an array of automatic storage duration whose length is determined at run time, when the array is declared.
If the C compiler supports GCC's
typeof
syntax either directly or through a different spelling of the keyword (e.g.,__typeof__
), defineHAVE_TYPEOF
. If the support is available only through a different spelling, definetypeof
to that spelling.
If function prototypes are understood by the compiler (as determined by
AC_PROG_CC
), definePROTOTYPES
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 the GNU C compiler andioctl
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.