use*_*250 3 c compiler-construction macros
我有一些基于编译器标志定义的宏.我正在尝试决定是否要将宏定义为(void)0或将其定义为未定义并导致编译时错误.
即
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...) (void)0
#endif
int main(void) {
...
PRINTF("something");
...
}
Run Code Online (Sandbox Code Playgroud)
与
#ifdef DEBUG
#define PRINTF(...) printf(__VA_ARGS__)
#endif
int main(void) {
...
#ifdef DEBUG
PRINTF("something");
#endif
...
}
Run Code Online (Sandbox Code Playgroud)
我不确定我喜欢哪种技术.一方面用#ifdef包装每个PRINTF语句都很难看.另一方面,如果我已经调用了一个在上下文中不起作用的函数,那么在编译时就知道了.
我认为决定因素是(void)0宏是否会影响可执行文件的大小.
编译代码时,(void)0会发生什么?如果PRINTF定义为(void)0,那是否意味着可执行文件将包含某种(void)0指令或是否会被完全忽略?
(void) 0;
Run Code Online (Sandbox Code Playgroud)
是一个没有副作用的表达式语句.任何理智的实现都会优化这个语句(实现可以用这样的语句做什么?).
具有(void) 0宏定义的C标准认可,因为它assert定义在(C11)7.2p1中,用于宏定义NDEBUG:
#define assert(ignore) ((void)0)
Run Code Online (Sandbox Code Playgroud)
注意定义:
#define PRINTF(...) (void)0
Run Code Online (Sandbox Code Playgroud)
代替
#define PRINTF(...)
Run Code Online (Sandbox Code Playgroud)
有一个优势.在第一种情况下,您有一个表达式(就像一个不返回值的函数),因此它可用于例如逗号表达式或条件表达式中.
例如:
// Comma expression
printf("test"), PRINTF("Hi Dennis");
// Conditional expression
test-expr ? perror("Hello") : PRINTF("world");
Run Code Online (Sandbox Code Playgroud)
这两个表达式语句仅对前一个PRINTF定义(with (void) 0)有效.