我有一个工作要使静态库更安全,为此,我需要替换printf
的格式化字符串,以使它们在已编译的静态库中以不同的方式出现,为此,必须在处理器阶段。
我所做的(并且它实际上在Visual Studio中有效)如下(,它只是一个伪示例):
char * my_array[] = {"abcd", "a %d", " b %d %s "};
#define GENERIC_ARRAY(x) my_array[x]
#define VARIADIC_DEBUG_PRINT(...) DebugPrintFunction (__FILE__, __LINE__, __func__, __VA_ARGS__)
#define PRINT_BY_LEVEL(x) VARIADIC_DEBUG_PRINT x
#define REPLACE_STRING(x,...) PRINT_BY_LEVEL((GENERAL_LEVEL,GENERIC_ARRAY(__COUNTER__),__VA_ARGS__))
#define MY_PRINTF(x,...) REPLACE_STRING((void*)0,(void*)0,__VA_ARGS__)
所有这些开销对我来说都是要欺骗编译器以接受不带任何参数(字符串除外)的打印
因此,当在我的main.c中进行测试时,我尝试了以下操作,并且有效:
MY_PRINTF("Hello World");
MY_PRINTF("My Val %d", i);
MY_PRINTF("MY VAL %d My String %s", i, s);
但是当切换到GCC时,他不喜欢第一张照片的格式,即:
MY_PRINTF("Hello World");
并抛出一个编译错误:
error: expected expression before ')' token
有什么想法可以欺骗编译器并接受它吗?还是更好的主意,如何在编译后安全地重命名字符串?
最佳答案
您可以尝试类似:
#include <stdio.h>
#define PRINT(x, ...) printf(x, ##__VA_ARGS__)
int main (int argc, char *argv[]) {
PRINT("Hello\n");
PRINT("World %d\n", 42);
return 0;
}
它适用于gcc 4.8(未尝试使用较早版本,但也应适用)