欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

怎样安全的使用可变参数宏__VA_ARGS__

发布时间:2025/7/14 编程问答 35 豆豆
生活随笔 收集整理的这篇文章主要介绍了 怎样安全的使用可变参数宏__VA_ARGS__ 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

  今天遇到一个关于可变参数的问题,下面先给出一个示例程序说明我遇到的问题。
0 #include <stdio.h>
1
2 #define print(fmt, ...) out(fmt, __VA_ARGS__)
3 #define out(fmt, ...) printf(fmt, __VA_ARGS__)
4
5 int main(int argc, char** argv)
6 {
7 print("hello %d\n", 0);
8 print("hello\n");
9 return 0;
10 }
  为了说明问题,上面有两个print宏调用,出问题的是第二个。 用gcc编译的时候给出错误提示:"7:2: error: expected expression before ')' token"。

  gcc的错误提示说明第8行的无参数的宏print调用是错误的。原因清晰,第八行的"hello\n"后面没有给出参数,导致"printf(fmt, __VA_ARGS__)"编译后成了"printf("hello\n", )",原因很清楚了。

  那么,为了去掉gcc 编译错误,我是不是得把第8行代码改成第7行的样式凑合着用?
  经过半天google,在 http://hi.baidu.com/pragmatist/item/591a8a4ccbd643086dc2f035 得到了答案(补充一下,百度真垃圾,自己搜自己的网页,还是没有给出我想要的答案)。文中有提示"##符号在 逗号 和 参数名 之间时不做连字符作用,而作为变参宏的特别用处",我急忙把程序修改成如下代码:
1 #include <stdio.h>
2
3 #define print(fmt, ...) out(fmt, __VA_ARGS__)
4 #define out(fmt, ...) printf(fmt, ##__VA_ARGS__)
5
6 int main(int argc, char** argv)
7 {
8 print("hello %d\n", 0);
9 print("hello\n");
10 return 0;
11 }
  我只修改了第4行的代码,此时gcc仍然给我相同的提示,难道我用错了?没办法了,只好找来同事帮忙。同事很给力了,一见代码,就见了亲人,说,再把第三行修改一下。最终代码如下:
1 #include <stdio.h>
2
3 #define print(fmt, ...) out(fmt, ##__VA_ARGS__)
4 #define out(fmt, ...) printf(fmt, ##__VA_ARGS__)
5
6 int main(int argc, char** argv)
7 {
8 print("hello %d\n", 0);
9 print("hello\n");
10 return 0;
11 }

  通过gcc -E test.c,得到如下代码:



int main(int argc, char** argv)
{
 printf("hello %d\n", 0);
 printf("hello\n");
 return 0;
}
  此时,预编译后的代码中第8行的结果中没有烦人的逗号,一切都很美好,gcc的错误提示没有了。再次领略静心细心的重要性。

  建议以后使用变参__VA_ARGS__都以##__VA_ARGS__的形式使用。

转载于:https://www.cnblogs.com/menggucaoyuan/archive/2012/10/11/2720466.html

总结

以上是生活随笔为你收集整理的怎样安全的使用可变参数宏__VA_ARGS__的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。