如何解决宏替换中%引发的GCC/MSVC格式警告问题?
解决宏断言中printf格式字符串的%警告问题
这个警告的根源在于宏展开后,#expr生成的字符串里包含了%符号,而printf会把这个%误认为是格式转换标识符,但后面没有对应的参数,因此触发了格式不匹配的警告。
比如你的代码中,AMP_Assert(a % 8 == 0)展开后,printf的格式字符串会变成:
"** Assertion failed: \"a % 8 == 0\" at %s:%d %s()\n"
这里面的a % 8里的%会被printf当成格式符,但没有对应的参数,所以编译器抛出警告。
最简单的解决方法:将断言表达式字符串作为独立参数传递
修改宏的定义,把#expr作为printf的一个单独参数,用%s来输出它,这样表达式里的%就不会被解析成格式转换符了:
#include <stdio.h> #define AMP_Assert( expr ) if( !(expr) ) { \ printf("** Assertion failed: \"%s\" at %s:%d %s()\n", #expr, __FILE__, __LINE__, __FUNCTION__);\ } int main(int argc, const char* argv[]) { int a = 1; AMP_Assert(a % 8 == 0); return 0; }
修改后,#expr生成的字符串"a % 8 == 0"会被当作普通字符串参数传给printf,里面的%会被直接输出,不会触发格式警告,同时在GCC和MSVC下都能正常编译。
为什么原来的写法会出问题?
原来的宏把#expr直接嵌入到了格式字符串中,预处理后格式字符串里的%会被printf的格式解析逻辑识别,而你并没有为这些额外的%提供对应的参数,所以编译器会检测到这个不匹配并发出警告。
内容的提问来源于stack exchange,提问作者ravin.wang
相关产品推荐
相关产品推荐

