关于 C 宏无效预处理令牌的错误
Posted
技术标签:
【中文标题】关于 C 宏无效预处理令牌的错误【英文标题】:error about C macro invalid preprocessing token 【发布时间】:2017-01-17 09:29:38 【问题描述】:// define the macro
#define FATAL(S,...) qDebug("%s,%s,%d,%s:"##S,"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
// call the macro
FATAL("not supported commandid:%d",cmdid);
虽然此代码在 Windows 下工作(Qt 与 msvc2010),但当我尝试在 macOS 下编译它(Qt 与 clang)时,我收到错误:::
粘贴形成的 "%s,%s,%d,%s:""不支持 commandid:%d",无效 预处理令牌。
如何让它在 macOS 下工作,或者有其他方法可以实现相同的功能吗?
【问题讨论】:
我宁愿把宏定义为#define FATAL(S,...) qDebug("[scribble],%s,%d,%s:" S,__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
见example
【参考方案1】:
标记## 放在逗号和变量参数之间时,只有表示可选参数的特殊含义:, ##__VA_ARGS__
这是对 C 语言的扩展。
在你的例子中,第二个参数是正确的,但不是第一个。
如果您不需要第一个参数是可选的,只需删除标记##:
#define FATAL(S,...) printf("%s,%s,%d,%s:"S, \
"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
但第一个参数也可以是可选的,使用另一个宏来扩展字符串文字和第一个参数,同时使第一个参数可选:
#include <stdlib.h>
#include <stdio.h>
#define MERGE_EXPAND( a , ... ) a __VA_ARGS__
#define MERGE( a , ... ) MERGE_EXPAND( a , ##__VA_ARGS__ )
#define FATAL(S,...) printf( MERGE( "%s,%s,%d,%s:",S), \
"[scribble]",__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__)
int main( void )
int cmdid = 12345;
FATAL();
puts( "" ) ;
FATAL( "first argument" );
puts( "" ) ;
FATAL( "first and second arguments: %d" , cmdid );
return EXIT_SUCCESS ;
【讨论】:
非常感谢。很强大。 另一个问题,为什么它不能在macos下工作,而是在windows下工作。 @Gavin Visual Studio 以不同的方式处理这个问题。以上是关于关于 C 宏无效预处理令牌的错误的主要内容,如果未能解决你的问题,请参考以下文章
配置 AccessDeniedHandler 以处理无效的 csrf 令牌
获取新的访问令牌以处理过期的访问令牌时,grant_type 参数无效或参数丢失