preprocessor, 'inline', and Apple's gcc
David Monniaux
David.Monniaux at imag.fr
Sun Mar 16 22:35:47 CET 2008
If one attempts linking multi-module programs using GMP on MacOS X 10.5,
using Apple's modified gcc 4.0.1 with the -std=c99, one gets errors
about duplicate symbols such as __gmpz_abs. The reason is that, in this
mode, Apple's gcc applies C99 semantics for the 'inline' keyword.
Accordingly, gmp.h tests whether this is the case (via the preprocessor
symbol __GNUC_STDC_INLINE_) and acts accordingly.
Problem: contrary to the "official" versions of gcc that have the same
behavior, Apple's gcc does not define __GNUC_STDC_INLINE__ in order to
signal that it enforces the new standard C behavior for 'inline' when
run in C99 mode.
This breaks linking certain programs such as APRON
(http://apron.cri.ensmp.fr/library/).
Proposed fix:
* test whether we're on gcc or compilers claiming to be compatible with it
** test whether we're on Apple's gcc
* test whether we're on a non-gcc C99-compliant compiler
* do other special cases
Your opinion?
#ifdef __GNUC__
/* Apple's cc applies C99 semantics in C99 mode but does not define
__GNUC_STDC_INLINE__ */
#ifdef __APPLE_CC__
#if defined(__STDC__) && defined(__STDC_VERSION__) && __STDC_VERSION__
>= 199901L
#define __GMP_EXTERN_INLINE inline
#else
#define __GMP_EXTERN_INLINE extern __inline__
#endif
#else /* __APPLE_CC__ */
#ifdef __GNUC_STDC_INLINE__
#define __GMP_EXTERN_INLINE extern __inline__ __attribute__
((__gnu_inline__))
#else
#define __GMP_EXTERN_INLINE extern __inline__
#endif
#define __GMP_INLINE_PROTOTYPES 1
#endif /* __APPLE_CC__ */
#elif defined(__STDC__) && __STDC__ >= 199901L /* __GNUC__*/
#define __GMP_EXTERN_INLINE inline
/* SCO OpenUNIX 8 cc supports "static inline foo()" but not in -Xc strict
ANSI mode (__STDC__ is 1 in that mode). Inlining only actually takes
place under -O. Without -O "foo" seems to be emitted whether it's used
or not, which is wasteful. "extern inline foo()" isn't useful, the
"extern" is apparently ignored, so foo is inlined if possible but also
emitted as a global, which causes multiple definition errors when
building a shared libgmp. */
#elif defined(__SCO_VERSION__)
#if __SCO_VERSION__ > 400000000 && __STDC__ != 1 \
&& ! defined (__GMP_EXTERN_INLINE)
#define __GMP_EXTERN_INLINE static inline
#endif
#endif
More information about the gmp-discuss
mailing list