On ons, 2009-12-16 at 10:49 -0500, Tom Lane wrote: > I think you're way overthinking this. Where we started was just > a proposal to try to expand the set of inline-ing compilers beyond > "gcc only". I don't see why we need to do anything but that. The > code is fine as-is except for the control #ifdefs.
I have found an Autoconf macro that checks whether the compiler properly supports C99 inline semantics. This would allow us to replace the __GNUC__ conditional with HAVE_C99_INLINE, in this case. Interestingly, however, this check results in GCC <=4.2 *not* supporting C99 inline, apparently because it produces redundant copies of static inline functions. But GCC 4.2 is currently Debian stable, for example, so de-supporting that is probably not yet an option. So, I'm not sure if this would actually solve anyone's problem, but it does call into question that exact semantics that we are looking for. Maybe we just replace __GNUC__ by __GNUC__ || __SOMETHING_ELSE_CC__. Patch attached for entertainment.
diff --git a/aclocal.m4 b/aclocal.m4 index 6d13d0c..1b32d4b 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,7 @@ dnl $PostgreSQL$ m4_include([config/ac_func_accept_argtypes.m4]) m4_include([config/acx_pthread.m4]) +m4_include([config/ax_c99_inline.m4]) m4_include([config/c-compiler.m4]) m4_include([config/c-library.m4]) m4_include([config/docbook.m4]) diff --git a/config/ax_c99_inline.m4 b/config/ax_c99_inline.m4 new file mode 100644 index 0000000..b6cbbd8 --- /dev/null +++ b/config/ax_c99_inline.m4 @@ -0,0 +1,62 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_c99_inline.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_C99_INLINE +# +# DESCRIPTION +# +# This macro defines HAVE_C99_INLINE if the C compiler supports "inline" +# and "extern inline" correctly. An application may replace "inline" with +# "static inline" as a workaround for older compilers. +# +# LICENSE +# +# Copyright (c) 2009 Michael McMaster <em...@michaelmcmaster.name> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +AC_DEFUN([AX_C99_INLINE], [ + AC_MSG_CHECKING([whether the compiler supports C99 inline functions]) + AC_REQUIRE([AC_PROG_CC_C99]) + + AC_LANG_PUSH([C]) + + dnl In a conforming C99 implementation a function marked "inline" will not + dnl be compiled into the translation unit if the compiler was not able to + dnl inline the function. + dnl GCC versions before 4.3 would output the inline functions into all + dnl translation units that could require the definition. + AC_LINK_IFELSE( + AC_LANG_SOURCE([ + inline void* foo() { foo(); return &foo; } + int main() { return foo() != 0;} + ]), + + dnl the invalid source compiled, so the inline keyword does not work + dnl correctly. + AC_MSG_RESULT([no]), + + dnl Secondary test of valid source. + AC_LINK_IFELSE( + AC_LANG_SOURCE([ + extern inline void* foo() { foo(); return &foo; } + int main() { return foo() != 0;} + ]), + + AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE_C99_INLINE], [1], + [Define to 1 if the "extern" keyword controls whether an inline function appears in a translation unit.]), + + dnl Perhaps inline functions aren't supported at all ? + AC_MSG_RESULT([no]) + ) + ) + + AC_LANG_POP([C]) + ]); diff --git a/configure.in b/configure.in index 5a27d3a..6d09d48 100644 --- a/configure.in +++ b/configure.in @@ -1088,6 +1088,7 @@ m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that. AC_C_BIGENDIAN AC_C_CONST AC_C_INLINE +AX_C99_INLINE AC_C_STRINGIZE PGAC_C_SIGNED AC_C_VOLATILE diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index 862a083..062459a 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -71,34 +71,34 @@ struct ListCell /* * These routines are used frequently. However, we can't implement * them as macros, since we want to avoid double-evaluation of macro - * arguments. Therefore, we implement them using GCC inline functions, - * and as regular functions with non-GCC compilers. + * arguments. Therefore, we implement them using inline functions, + * if the compiler supports it. */ -#ifdef __GNUC__ +#ifdef HAVE_C99_INLINE -static __inline__ ListCell * +static inline ListCell * list_head(List *l) { return l ? l->head : NULL; } -static __inline__ ListCell * +static inline ListCell * list_tail(List *l) { return l ? l->tail : NULL; } -static __inline__ int +static inline int list_length(List *l) { return l ? l->length : 0; } -#else +#else /* HAVE_C99_INLINE */ extern ListCell *list_head(List *l); extern ListCell *list_tail(List *l); extern int list_length(List *l); -#endif /* __GNUC__ */ +#endif /* HAVE_C99_INLINE */ /* * NB: There is an unfortunate legacy from a previous incarnation of diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 69799a5..4ee950a 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -84,6 +84,10 @@ /* Define to 1 if you have the `atexit' function. */ #undef HAVE_ATEXIT +/* Define to 1 if the "extern" keyword controls whether an inline function + appears in a translation unit. */ +#undef HAVE_C99_INLINE + /* Define to 1 if you have the `cbrt' function. */ #undef HAVE_CBRT diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 93c2cfb..1947efa 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -72,11 +72,11 @@ extern void *repalloc(void *pointer, Size size); /* * MemoryContextSwitchTo can't be a macro in standard C compilers. - * But we can make it an inline function when using GCC. + * But we can make it an inline function if the compiler supports it. */ -#ifdef __GNUC__ +#ifdef HAVE_C99_INLINE -static __inline__ MemoryContext +static inline MemoryContext MemoryContextSwitchTo(MemoryContext context) { MemoryContext old = CurrentMemoryContext; @@ -84,10 +84,10 @@ MemoryContextSwitchTo(MemoryContext context) CurrentMemoryContext = context; return old; } -#else +#else /* not HAVE_C99_INLINE */ extern MemoryContext MemoryContextSwitchTo(MemoryContext context); -#endif /* __GNUC__ */ +#endif /* not HAVE_C99_INLINE */ /* * These are like standard strdup() except the copied string is
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers