gcc 3.4 gives a warning for all (valid or invalid) uses of
APR_REGISTER_OPTIONAL_FN and APR_OPTIONAL_HOOK: e.g.:
mpm_common.c:894: warning: function called through a non-compatible type
(this is emitted even without -Wall)
>From delving through C99, this appears to be a valid warning, since the
code has undefined behaviour by section 6.3.2.3 para 8. (which says, to
try and paraphrase: behaviour is undefined if you call a function
through a function pointer where the function and the function pointer
don't have compatible types)
Given that, I don't see how these macros can be written to be both
conformant C and type-safe. It can be be made type-safe using GCC
extensions, for instance, as below: any better ideas?
It might be prudent to also make the !__GNUC__ case valid C but not
type-safe, by casting the pfn argument rather than casting
apr_dynamic_fn_register itself.
Index: include/apr_optional.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_optional.h,v
retrieving revision 1.12
diff -u -r1.12 apr_optional.h
--- include/apr_optional.h 16 Nov 2003 01:50:10 -0000 1.12
+++ include/apr_optional.h 5 Feb 2004 16:36:19 -0000
@@ -105,9 +105,18 @@
* confusingly but correctly, the function itself can be static!
* @param name The name of the function
*/
+#ifdef __GNUC__
+#define APR_REGISTER_OPTIONAL_FN(name) do { \
+ APR_OPTIONAL_FN_TYPE(name) apu__opt1; \
+ typeof(name) apu__opt2; \
+ (void) (&apu__opt1 == &apu__opt2); \
+ apr_dynamic_fn_register(#name,(apr_opt_fn_t *)name); \
+} while (0)
+#else
#define APR_REGISTER_OPTIONAL_FN(name) \
(((void (*)(const char *, APR_OPTIONAL_FN_TYPE(name) *)) \
&apr_dynamic_fn_register)(#name,name))
+#endif
/** @internal
* Private function! DO NOT USE!
Index: include/apr_optional_hooks.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_optional_hooks.h,v
retrieving revision 1.9
diff -u -r1.9 apr_optional_hooks.h
--- include/apr_optional_hooks.h 1 Jan 2003 00:02:20 -0000 1.9
+++ include/apr_optional_hooks.h 5 Feb 2004 16:36:19 -0000
@@ -99,10 +99,20 @@
* @param nOrder an integer determining order before honouring aszPre and
aszSucc (for example HOOK_MIDDLE)
*/
+#ifdef __GNUC__
+#define APR_OPTIONAL_HOOK(ns,name,pfn,aszPre,aszSucc,nOrder) \
+do { \
+ ns##_HOOK_##name##_t apu__opt1; \
+ typeof(pfn) apu__opt2; \
+ (void) (&apu__opt1 == &apu__opt2); \
+ apr_optional_hook_add(#name,(apr_opt_fn_t *)pfn,aszPre, aszSucc, nOrder); \
+} while (0)
+#else
#define APR_OPTIONAL_HOOK(ns,name,pfn,aszPre,aszSucc,nOrder) \
((void (APR_THREAD_FUNC *)(const char *,ns##_HOOK_##name##_t *,const char
* const *, \
const char * const
*,int))&apr_optional_hook_add)(#name,pfn,aszPre, \
aszSucc, nOrder)
+#endif
/**
* @internal