您为什么不简单地根据该宏定义 ASSERT?
#ifdef MACRO
#define ASSERT(NAME, TEST) \
do { \
printf("Assert failed"); \
} while(0)
#else
#define ASSERT(NAME, TEST) {}
#endif
应避免在 C 条件语句中使用固定的预处理器值 - 确保编译器应该优化死代码,但是当您可以从本质上删除实际的 C 代码时,为什么还要依赖它呢?
编辑:
有一个相当丑的技巧涉及宏参数字符串化,您可能可以使用:
#include <string.h>
#include <stdio.h>
#define X
#define ERROR_(NAME, TEXT) \
if (strcmp("", #NAME) == 0) \
printf("%s\n", TEXT)
#define ERROR(n, t) ERROR_(n, t)
int main() {
ERROR(X, "Error: X");
ERROR(Y, "Error: Y");
return 0;
}
这个输出:
$ ./test
Error: X
本质上,它使用的事实是,当预处理器标记不定义为宏时,它会扩展为自身。另一方面,当它 is 定义时,它会扩展为空字符串或其定义。除非您的某个宏有自己的名称作为定义,否则这个 hack 应该可以工作。
免责声明:使用此功能需您自担风险!
(...因为我肯定不会使用它!)
编辑 2:
上面程序的gcc -O0 -S的汇编输出是:
.file "test.c"
.section .rodata
.LC0:
.string "Error: X"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.4.3"
.section .note.GNU-stack,"",@progbits
即使没有优化,GCC 也会将此程序简化为单个 puts() 调用。该程序产生完全相同的汇编输出:
#include <stdio.h>
int main() {
puts("Error: X");
return 0;
}
因此,您可能不会有任何性能问题,具体取决于您的编译器和任何优化...