File: autoconf.info, Node: C++ Compiler, Next: C++ Compiler, Prev: Generic Compiler Characteristics, Up: Compilers and Preprocessors 5.10.3 C Compiler Characteristics --------------------------------- 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. Don't use lines containing solitary backslashes 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. Don't compile several files at once if output matters to you 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. Don't rely on ‘#error’ failing The 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. Don't rely on correct ‘#line’ support On Solaris, ‘c89’ (at least through Oracle Developer Studio 12.6) diagnoses ‘#line’ directives whose line numbers are greater than 32767. Nothing in Posix makes this invalid. That is why Autoconf stopped issuing ‘#line’ directives. -- Macro: AC_PROG_CC ([COMPILER-SEARCH-LIST]) Determine a C compiler to use. If the environment variable ‘CC’ is set, its value will be taken as the name of the C compiler to use. Otherwise, search for a C compiler under a series of likely names, trying ‘gcc’ and ‘cc’ first. Regardless, the output variable ‘CC’ is set to the chosen compiler. If the optional first argument to the macro is used, it must be a whitespace-separated list of potential names for a C compiler, which overrides the built-in list. If no C compiler can be found, ‘configure’ will error out. If the selected C compiler is found to be GNU C (regardless of its name), the shell variable ‘GCC’ will be set to ‘yes’. If the shell variable ‘CFLAGS’ was not already set, it is set to ‘-g -O2’ for the GNU C compiler (‘-O2’ on systems where GCC does not accept ‘-g’), or ‘-g’ for other compilers. ‘CFLAGS’ is then made an output variable. You can override the default for ‘CFLAGS’ by inserting a shell default assignment between ‘AC_INIT’ and ‘AC_PROG_CC’: : ${CFLAGS="OPTIONS"} where OPTIONS are the appropriate set of options to use by default. (It is important to use this construct rather than a normal assignment, so that ‘CFLAGS’ can still be overridden by the person building the package. *Note Preset Output Variables::.) If necessary, options are added to ‘CC’ to enable support for ISO Standard C features with extensions, preferring the newest edition of the C standard for which detection is supported. Currently the newest edition Autoconf knows how to detect support for is C11, as there is little reason to prefer C17 to C11, and C23 is still too new. After calling this macro you can check whether the C compiler has been set to accept standard C by inspecting the shell variable ‘ac_prog_cc_stdc’. Its value will be ‘c11’, ‘c99’, or ‘c89’, respectively, if the C compiler has been set to use the 2011, 1999, or 1990 edition of the C standard, and ‘no’ if the compiler does not support compiling standard C at all. The tests for standard conformance are not comprehensive. They test the values of ‘__STDC__’ and ‘__STDC_VERSION__’, and a representative sample of the language features added in each version of the C standard. They do not test the C standard library, because the C compiler might be generating code for a "freestanding environment" (in which most of the standard library is optional). If you need to know whether a particular C standard header exists, use ‘AC_CHECK_HEADER’. None of the options that may be added to ‘CC’ by this macro enable _strict_ conformance to the C standard. In particular, system-specific extensions are not disabled. (For example, for GNU C, the ‘-std=gnuNN’ options may be used, but not the ‘-std=cNN’ options.) 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. Although ‘AC_PROG_CC’ is safe to directly expand multiple times, it performs certain checks (such as the proper value of ‘EXEEXT’) only on the first invocation. Therefore, care must be used when invoking this macro from within another macro rather than at the top level (*note Expanded Before Required::). -- Macro: AC_PROG_CC_C_O 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. -- Macro: AC_PROG_CPP Set output variable ‘CPP’ to a command that runs the C preprocessor. If ‘$CC -E’ doesn't work, tries ‘cpp’ and ‘/lib/cpp’, in that order. 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. -- Macro: AC_PROG_CPP_WERROR 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’ (*note Running the Compiler::) or ‘AC_RUN_IFELSE’ (*note Runtime::). -- Macro: AC_C_BACKSLASH_A 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. -- Macro: AC_C_BIGENDIAN ([ACTION-IF-TRUE], [ACTION-IF-FALSE], [ACTION-IF-UNKNOWN], [ACTION-IF-UNIVERSAL]) 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 architectures with differing endianness. 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 (*note 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. -- Macro: AC_C_CONST 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. -- Macro: AC_C__GENERIC If the C compiler supports C11-style generic selection using the ‘_Generic’ keyword, define ‘HAVE_C__GENERIC’. -- Macro: AC_C_RESTRICT 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. -- Macro: AC_C_VOLATILE 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. *Note 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. -- Macro: AC_C_INLINE 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. -- Macro: AC_C_CHAR_UNSIGNED 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#if CHAR_MIN == 0 # define CHAR_UNSIGNED 1 #endif -- Macro: AC_C_STRINGIZE 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. -- Macro: AC_C_FLEXIBLE_ARRAY_MEMBER 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); -- Macro: AC_C_VARARRAYS 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__’. -- Macro: AC_C_TYPEOF 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. -- Macro: AC_C_PROTOTYPES 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.