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