首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC中预处理器VARIADIC宏的欺骗

GCC中预处理器VARIADIC宏的欺骗
EN

Stack Overflow用户
提问于 2014-01-20 13:31:51
回答 2查看 759关注 0票数 1

我的任务是使静态库更安全,为此我需要替换printf的格式化字符串,以便它们在编译的静态库中以不同的形式出现,这必须在预处理阶段完成。

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

代码语言:javascript
复制
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__)

所有这些开销都是让我欺骗编译器接受除了字符串之外没有任何参数的打印。

因此,在我的主机上测试它时,我尝试了以下几种方法,并且成功了:

代码语言:javascript
复制
MY_PRINTF("Hello World");
MY_PRINTF("My Val %d", i);
MY_PRINTF("MY VAL %d My String %s", i, s);

但是,当他转向GCC时,他不喜欢第一张印刷版的格式,即:

代码语言:javascript
复制
MY_PRINTF("Hello World");

并抛出一个编译错误:

代码语言:javascript
复制
error: expected expression before ')' token

有什么想法吗?我怎样才能欺骗编译器并接受它呢?或者更好的想法是如何在编译后安全地重命名字符串?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-20 13:50:34

你可以尝试这样的方法:

代码语言:javascript
复制
#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 (以前的版本没有尝试过,但也应该有效)

票数 4
EN

Stack Overflow用户

发布于 2014-01-20 14:38:24

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

代码语言:javascript
复制
#define MY_PRINTF(x, ...) \ 
    VARIADIC_DEBUG_PRINT(GENERAL_LEVEL, GENERIC_ARRAY(__COUNTER__), (void*)0, (void*)0, ##__VA_ARGS__)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21235422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档