Рассмотрим следующие два макроса:
#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 ) ; \
} \
}
Теперь рассмотрим пример использования этих:
PNORM( verbose, "\tSomeText [%d] More [%p]\r\n", 0, ptr ) ;
При компиляции с параметром -pedantic и -std = c99 я получаю эту ошибку много раз:
mycode.c:410:112: warning: ISO C99 requires rest arguments to be used
Ответчик прав, жалуясь на это, но есть ли простой способ подавить это предупреждение, поскольку меня это не волнует?
Ответ 1
Объедините аргумент s
с переменными аргументами, чтобы вы всегда имели хотя бы один аргумент как часть многоточия. Это также позволяет избежать использования расширения ,##
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
Ток ##
в сочетании с __VA_ARGS__
является расширением gcc, которое не является частью ISO C99. Вот почему вы получаете предупреждение.
Ответ 3
Вы можете отключить предупреждения только вокруг своих макросов или полностью отключить специальное предупреждение с помощью pragma Warnings
в GCC. Вы также не можете использовать -pedantic
, так как это, ну, педантично.
Ответ 4
В зависимости от того, что для вас просто. В P99 есть условные обозначения P99, которые позволят вам делать что-то вроде
#define USER_MACRO(...) P99_IF_DEC_LE(P99_NARG(__VA_ARGS__),2)(USER_MACRO2(__VA_ARGS__))(USER_MACRO3(__VA_ARGS__))
Таким образом, нет необходимости в расширении ,##
gcc.