Chinaunix

标题: CU牛人多,帮忙看看这个define的用法? [打印本页]

作者: 鬼鬼一哈    时间: 2014-04-20 06:57
标题: CU牛人多,帮忙看看这个define的用法?
本帖最后由 鬼鬼一哈 于 2014-04-20 06:58 编辑
  1. #include <stddef.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>


  5. #define TRACE_NULL           0x0000
  6. #define TRACE_DEBUG          0x0001
  7. #define TRACE_INFO           0x0002
  8. #define TRACE_ERROR          0x0004

  9. struct test_struct {
  10.     unsigned int a;
  11.     unsigned int b;
  12. };

  13. #define dump(resrc, level, fmt, args, ...) \
  14.     do{\
  15.         printf("2.0 resource: %p\n", resrc);\
  16.         struct test_struct *Presource = (struct test_struct *)resrc ;\
  17.         printf("3.0 resource: %p, %d\n", Presource, Presource->a);\
  18.         \
  19.         if (level) {\
  20.             printf("4.0 (func:%s line:%4d):"fmt"", __func__, __LINE__,#args);\
  21.         }\
  22.     }while(0)



  23. int main() {
  24.     struct test_struct resource;
  25.     resource.a = 10;
  26.     resource.b = 20;
  27.    
  28.     printf("1.0 resource: %p, %d\n", &resource, resource.b);

  29.     dump(&resource, TRACE_DEBUG, "resource: %d\n", resource.b);
  30.    
  31. }
复制代码
执行结果为:
1.0 resource: 0xbfbdd084, 20
2.0 resource: 0xbfbdd084
3.0 resource: 0xbfbdd084, 10
4.0 (func:main line:  37):resource: 134514094 错误在哪里呢?
作者: linux_c_py_php    时间: 2014-04-20 10:05
printf("4.0 (func:%s line:%4d):"fmt"", __func__, __LINE__,#args);

引号不转义,这能编译过?
作者: folklore    时间: 2014-04-20 11:49
没问题, 唯一可能出问题的是变参数宏的使用, 这个好像没有标准化(?), 故要说出编译器
作者: 鬼鬼一哈    时间: 2014-04-20 14:17

folklore 发表于 2014-04-20 11:49
没问题, 唯一可能出问题的是变参数宏的使用, 这个好像没有标准化(?), 故要说出编译器

gcc version 4.7.2 20130108
作者: linux_c_py_php    时间: 2014-04-21 10:09
##__VA_ARGS__呢?
作者: Hugo801122    时间: 2014-04-21 10:39
没啥,就是替代了一段代码,经常看到,整的好复杂。
作者: wercedes    时间: 2014-04-21 12:58
gcc -E 之后看到
if (0x0001) { printf("4.0 (func:%s line:%4d):""resource: %d\n""", __func__, 37,"resource.b");
%4d出来的是字符串"resource.b"在内存中的地址.
作者: socay2    时间: 2014-04-21 13:42
linux_c_py_php 发表于 2014-04-20 10:05
printf("4.0 (func:%s line:%4d):"fmt"", __func__, __LINE__,#args);

引号不转义,这能编译过?

如果单独的 printf 这样写应该需要转义,但是在宏中,预处理器能够将器替换成字符串,而 printf("a""b") 这种形式编译器是支持的,所以应该没问题。

真没看出来问题在哪里!
作者: 道痞    时间: 2014-04-21 15:06
wercedes 发表于 2014-04-21 12:58
gcc -E 之后看到
if (0x0001) { printf("4.0 (func:%s line:%4d):""resource: %d\n""", __func__, 37,"res ...


问题如七楼所说,
#define dump(resrc, level, fmt,...) \
......
            printf("4.0 (func:%s line:%4d):"fmt"", __func__, __LINE__,__VA_ARGS__);\
        }\
    }while(0)

or

#define dump(resrc, level, fmt,args...) \
.......
            printf("4.0 (func:%s line:%4d):"fmt"", __func__, __LINE__,##args);\
        }\
    }while(0)

个人喜欢第一种风格


作者: pandaiam    时间: 2014-04-21 15:51
应该是一个是c标准的变参宏,一个是gcc的变参宏
作者: 鬼鬼一哈    时间: 2014-04-21 21:31
回复 7# wercedes

恩,学到了一招,多谢了。
   
作者: 鬼鬼一哈    时间: 2014-04-21 21:31
回复 9# 道痞


是的,多谢
   
作者: file3    时间: 2014-05-04 19:45
应该是vprintf吧。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2