可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Consider the following two macros:
#define PNORM( v, s, ... ) { \ if( VERBOSITY_CHECK( v ) ) { \ if( ( errno = pthread_mutex_lock(&server.output_mutex) ) ) { \ PERROR_LOCKFREE( normal, "\tpthread_mutex_lock failed on output_mutex.\r\n" ) ; \ } \ fprintf( stdout, s, ## __VA_ARGS__ ) ; \ fflush( stdout ) ; \ if( ( errno = pthread_mutex_unlock(&server.output_mutex) ) ) { \ PERROR_LOCKFREE( normal, "\tpthread_mutex_unlock failed on output_mutex.\r\n" ) ; \ } \ } \ } #define PERROR_LOCKFREE( v, s, ... ) { \ if( VERBOSITY_CHECK( v ) ) { \ PERRNO ;\ fprintf( stderr, s, ## __VA_ARGS__ ) ; \ fflush( stderr ) ; \ } \ }
Now consider an example use of these:
PNORM( verbose, "\tSomeText [%d] More [%p]\r\n", 0, ptr ) ;
When compiled with the -pedantic option and -std=c99 I get this error many times:
mycode.c:410:112: warning: ISO C99 requires rest arguments to be used
The complier is right in complaining about this but is there a simple way I can suppress this warning since I don't care about it?
回答1:
Combine the s
argument with the variadic arguments so that you always have at least one argument as part of the ellipsis. This also allows you to avoid using the ,##
extension of GCC:
#define PNORM( v, ... ) { \ if( VERBOSITY_CHECK( v ) ) { \ if( ( errno = pthread_mutex_lock(&server.output_mutex) ) ) { \ PERROR_LOCKFREE( normal, "\tpthread_mutex_lock failed on output_mutex.\r\n" ) ; \ } \ fprintf( stdout, __VA_ARGS__ ) ; \ fflush( stdout ) ; \ if( ( errno = pthread_mutex_unlock(&server.output_mutex) ) ) { \ PERROR_LOCKFREE( normal, "\tpthread_mutex_unlock failed on output_mutex.\r\n" ) ; \ } \ } \ } #define PERROR_LOCKFREE( v, ... ) { \ if( VERBOSITY_CHECK( v ) ) { \ PERRNO ;\ fprintf( stderr, __VA_ARGS__ ) ; \ fflush( stderr ) ; \ } \ }
回答2:
The ##
token in combination with __VA_ARGS__
is a gcc extension that's not part of ISO C99. That's why you're getting the warning.
回答3:
You can disable warnings just around your macros, or disable the specific warning entirely with pragma Warnings
in GCC. You could also not use -pedantic
, since it is, well, pedantic.
回答4:
Depends on what is simple for you. In P99 there are P99 conditionals that would allow you doing something like
#define USER_MACRO(...) P99_IF_DEC_LE(P99_NARG(__VA_ARGS__),2)(USER_MACRO2(__VA_ARGS__))(USER_MACRO3(__VA_ARGS__))
So with that there is no need for the ,##
extension of gcc.