LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 883|回复: 5

问 一个宏的问题

[复制链接]
发表于 2007-9-19 15:32:39 | 显示全部楼层 |阅读模式
在asterisk的源代码中看到的一个宏:
  1. struct ast_flags {
  2.         unsigned int flags;
  3. };
  4. extern unsigned int __unsigned_int_flags_dummy;
  5. #define ast_test_flag(p,flag)           ({ \ //这里的p是struct ast_flags*类型的
  6.                                         typeof ((p)->flags) __p = (p)->flags; \//这一行和下面两行是在干什么呢?
  7.                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
  8.                                         (void) (&__p == &__x); \
  9.                                         ((p)->flags & (flag)); \
  10.                                         })
  11. #define ast_set_flag(p,flag)            do { \
  12.                                         typeof ((p)->flags) __p = (p)->flags; \ //这一行和下面两行是在干什么呢?
  13.                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
  14.                                         (void) (&__p == &__x); \
  15.                                         ((p)->flags |= (flag)); \
  16.                                         } while(0)
复制代码

谢谢
发表于 2007-9-19 16:22:34 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-19 18:02:14 | 显示全部楼层
typeof我当然知道,我只是不知道那两行有什么意义。
要是我自己来写这个宏的话,我想我一定会写成这个样子:
  1. #define ast_set_flag(p,flag)            do { \
  2.                                         typeof ((p)->flags) f = (flag); \
  3.                                         ((p)->flags |= f); \
  4.                                         } while(0)
  5. 甚至直接就是:
  6. #define ast_set_flag(p,flag) (p)->flags |= (flag)
复制代码
这两个有多大的本质上的区别呢??
回复 支持 反对

使用道具 举报

发表于 2007-9-19 21:08:38 | 显示全部楼层
Don't you read the comment above the macros?
  1. /*! \note
  2. \verbatim
  3.    Note:
  4.    It is very important to use only unsigned variables to hold
  5.    bit flags, as otherwise you can fall prey to the compiler's
  6.    sign-extension antics if you try to use the top two bits in
  7.    your variable.
  8.    The flag macros below use a set of compiler tricks to verify
  9.    that the caller is using an "unsigned int" variable to hold
  10.    the flags, and nothing else. If the caller uses any other
  11.    type of variable, a warning message similar to this:
  12.    warning: comparison of distinct pointer types lacks cast
  13.    will be generated.
  14.    The "dummy" variable below is used to make these comparisons.
  15.    Also note that at -O2 or above, this type-safety checking
  16.    does _not_ produce any additional object code at all.
  17. \endverbatim
  18. */
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-9-20 09:33:36 | 显示全部楼层
Post by herberteuler
Don't you read the comment above the macros?
  1. /*! \note
  2. \verbatim
  3.    Note:
  4.    It is very important to use only unsigned variables to hold
  5.    bit flags, as otherwise you can fall prey to the compiler's
  6.    sign-extension antics if you try to use the top two bits in
  7.    your variable.

  8.    The flag macros below use a set of compiler tricks to verify
  9.    that the caller is using an "unsigned int" variable to hold
  10.    the flags, and nothing else. If the caller uses any other
  11.    type of variable, a warning message similar to this:

  12.    warning: comparison of distinct pointer types lacks cast
  13.    will be generated.

  14.    The "dummy" variable below is used to make these comparisons.

  15.    Also note that at -O2 or above, this type-safety checking
  16.    does _not_ produce any additional object code at all.
  17. \endverbatim
  18. */
复制代码

不好意思,这个我倒确实没有注意,thx
回复 支持 反对

使用道具 举报

发表于 2007-9-20 13:27:31 | 显示全部楼层
Post by Arthur.Echo
不好意思,这个我倒确实没有注意,thx
不用不好意思,如果一个开源项目的源代码足够好的话,通常它提供的资源里没有什么是无用的,不看就浪费了。注释只是这其中的一部分。多多注意哦
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表