Bruno Haible <bruno <at> clisp.org> writes:
> There is one trick needed, though. Suppose the system has a function which may
> be declared as
> int foo (void *p);
> or int foo (char *p);
> How can we add the attribute?
> - The trick is to write
> #if HAVE_DECL_FOO
> extern __typeof__(foo) foo __attribute__ ((__warning__ ("message")));
> #endif
In C++, that works if there is no overload resolution. But in the case of
overload resolution, it won't work:
$ cat foo.c
#ifdef __cplusplus
static void bar (void) {}
static void bar (char) {}
extern __typeof__ (bar) bar __attribute__ ((__warning__ ("message2")));
#endif
$ gcc -o foo.o foo.c
foo.c:4: error: type of ‘bar’ is unknown
foo.c:4: error: invalid type in declaration before ‘;’ token
foo.c:4: error: ‘int bar’ redeclared as different kind of symbol
foo.c:3: error: previous declaration of ‘void bar(char)’
$
I was hoping to write:
#if <new enough gcc...>
# define _GL_WARN_ON_USE (func, message) \
extern __typeof__(func) func __attribute__ ((__warning__ (message)))
#else
# define _GL_WARN_ON_USE (func, message) \
typedef int dummy
#endif
#ifdef GNULIB_POSIXCHECK
_GL_WARN_ON_USE (printf, "printf is not portable,...");
#endif
But that appears to only work for C, since I cannot know in advance whether a
macro name will have overloads in C++. A real case of this is for functions
like strchr, which are reasonably typed one way in C:
char *strchr (const char *, int);
and two different ways in C++:
const char *strchr (const char *, int);
char *strchr (char *, int);
Any suggestions on a way to manage this? Maybe some sort of way to use
template SFINAE to silently suppress the attempt if the declaration is
overloaded? Or am I stuck using:
#if <new enough gcc...> && !defined __cplusplus
# define _GL_WARN_ON_USE...
#endif
--
Eric Blake