在GCC中欺骗预处理器VARIADIC MACROS

时间:2014-01-20 13:31:52

标签: c++ c visual-studio-2010 gcc variadic-macros

我有一项工作要使静态库更安全,为了做到这一点,我需要替换printf的格式化字符串,使它们在编译的静态库中以不同的方式显示,以便实现此目的它必须在预处理器阶段完成。

我所做的(实际上它在视觉工作室中有效)如下(,它只是一个伪示例):

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

任何想法如何欺骗编译器并接受它?或者更好的想法如何在编译后安全地重命名字符串?

2 个答案:

答案 0 :(得分:4)

您可以尝试以下内容:

#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(未尝试使用早期版本,但它也可以使用)

答案 1 :(得分:1)

使用##__VA_ARGS__,您可以尝试:

#define MY_PRINTF(x, ...) \ 
    VARIADIC_DEBUG_PRINT(GENERAL_LEVEL, GENERIC_ARRAY(__COUNTER__), (void*)0, (void*)0, ##__VA_ARGS__)