Here's the error: conftest.c:84:16: error: initializer element is not a compile-time constant int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); here's where it comes from: configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "strace" | #define PACKAGE_TARNAME "strace" | #define PACKAGE_VERSION "4.5.20" | #define PACKAGE_STRING "strace 4.5.20" | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define PACKAGE "strace" | #define VERSION "4.5.20" | #define LINUX 1 | #define X86_64 1 | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 | #define HAVE_MEMORY_H 1 | #define HAVE_STRINGS_H 1 | #define HAVE_INTTYPES_H 1 | #define HAVE_STDINT_H 1 | #define HAVE_UNISTD_H 1 | #define __EXTENSIONS__ 1 | #define _ALL_SOURCE 1 | #define _GNU_SOURCE 1 | #define _POSIX_PTHREAD_SEMANTICS 1 | #define _TANDEM_SOURCE 1 | #define STDC_HEADERS 1 | /* end confdefs.h. */ | | #include <stdbool.h> | #ifndef bool | "error: bool is not defined" | #endif | #ifndef false | "error: false is not defined" | #endif | #if false | "error: false is not 0" | #endif | #ifndef true | "error: true is not defined" | #endif | #if true != 1 | "error: true is not 1" | #endif | #ifndef __bool_true_false_are_defined | "error: __bool_true_false_are_defined is not defined" | #endif | | struct s { _Bool s: 1; _Bool t; } s; | | char a[true == 1 ? 1 : -1]; | char b[false == 0 ? 1 : -1]; | char c[__bool_true_false_are_defined == 1 ? 1 : -1]; | char d[(bool) 0.5 == true ? 1 : -1]; | bool e = &s; | char f[(_Bool) 0.0 == false ? 1 : -1]; | char g[true]; | char h[sizeof (_Bool)]; | char i[sizeof s.t]; | enum { j = false, k = true, l = false * true, m = true * 256 }; | /* The following fails for | HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ | _Bool n[m]; | char o[sizeof n == m * sizeof n[0] ? 1 : -1]; | char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; | # if defined __xlc__ || defined __GNUC__ | /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 | reported by James Lemley on 2005-10-05; see | http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html | This test is not quite right, since xlc is allowed to | reject this program, as the initializer for xlcbug is | not one of the forms that C requires support for. | However, doing the test right would require a runtime | test, and that would make cross-compilation harder. | Let us hope that IBM fixes the xlc bug, and also adds | support for this kind of constant expression. In the | meantime, this test will reject xlc, which is OK, since | our stdbool.h substitute should suffice. We also test | this with GCC, where it should work, to detect more | quickly whether someone messes up the test in the | future. */ | char digs[] = "0123456789"; | int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); | # endif | /* Catch a bug in an HP-UX C compiler. See | http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html | http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html | */ | _Bool q = true; | _Bool *pq = &q; | | int | main () | { | | *pq |= q; | *pq |= ! q; | /* Refer to every declared value, to avoid compiler optimizations. */ | return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l | + !m + !n + !o + !p + !q + !pq); | | ; | return 0; | } I'm not sure who's at fault here. This does mean that clang can't compile strace right away, though, because configure (generated by autoconf 2.65) considers clang's <stdbool.h> useless and the type bool is used in the code (albeit for exactly one variable).
This autoconf test is generating non-compliant code, and emulating GCC's bug would be non-trivial. This: &(diags+5)[-1] == &diags[4] is not an integer constant expression, therefore it can't be used to initialize a global in C. Perhaps the xlcbug case can be ifdef'd with an xlc-specific macro or something.
GCC's behavior is not a bug; the standard is explicit that implementations may accept additional forms of constant expression (6.6p10). strace's reliance on nonstandard behavior is a bug. Whoever wrote the long comment in the configure file seems to understand this.
Note that the expression in question is _already_ inside a block guarded by: # if defined __xlc__ || defined __GNUC__ Are you telling me that clang defines __GNUC__, but does not support all of the gcc extensions? If so, it is a lie, and doing a disservice to users. Is there another preprocessor macro that can reliably be used to tell when clang, rather than gcc, is being used as the compiler?
It may be a lie, but I don't think it's a disservice to users; not defining __GNUC__ would break far more stuff than defining it does. People have tried. The macro __clang__ can be used to test for clang. That seems like a good solution to the problem.
(For the sake of keeping pointers around:) I reported this to autoconf upstream at http://lists.gnu.org/archive/html/bug-autoconf/2010-08/msg00103.html , and it looks like they will change the test in some way to avoid rejecting clang.