• 怎样安全的使用可变参数宏__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__的形式使用。

  • 相关阅读:
    webservice呈现调用导致呈现当机.
    【ES6】Promise用法
    腾讯地图JavaScript API调用
    【微信小程序】微信开发者工具快捷键汇总
    【微信小程序】小程序模拟调用本地json接口数据
    【微信小程序】小程序系统API
    【git和GitHub】分布式版本控制Git和代码远程仓库GitHub
    【微信小程序】组件化开发
    【微信小程序】小程序开发注意事项
    【微信小程序】引入外部js 方法
  • 原文地址:https://www.cnblogs.com/menggucaoyuan/p/2720466.html
Copyright © 2020-2023  润新知