【问题标题】:What is the need for __NSX_PASTE__ to define a macro?__NSX_PASTE__ 定义宏需要什么?
【发布时间】:2016-02-20 06:24:43
【问题描述】:

让我们通过这篇文章回顾一下Clang的MIN宏:Deep learning IOS development of macro。最终结果是what you can also find here

#define __NSX_PASTE__(A,B) A##B

#define __NSMIN_IMPL__(A,B,L) ({\
        __typeof__(A) __NSX_PASTE__(__a,L) = (A);\
        __typeof__(B) __NSX_PASTE__(__b,L) = (B);\
        (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L);\
        })

但我不明白定义__NSX_PASTE__ 的必要性。直接使用岂不是一样更易读:

#define __NSMIN_IMPL__(A,B,L) ({\
        __typeof__(A) __a##L = (A);\
        __typeof__(B) __b##L = (B);\
        (__a##L < __b##L) ? __a##L : __b##L;\
        })

【问题讨论】:

标签: objective-c macros clang min


【解决方案1】:

简单的答案是__NSX_PASTE__ 是必需的,因为没有它__COUNTER__ 宏(问题中未显示,但请参阅链接文章中的完整源代码,或查看Apple 的NSObjCRuntime.h 中的定义)不会被扩大。这是由于 C 预处理器的奇怪而奇妙的工作方式以及它如何处理 stringificationconcatenation,阅读所有这些工作原理的好地方是 GCC documentation on macros

要查看带有和不带有 __NSX_PASTE__ 的结果,请将上述宏放入测试文件中,例如 test.m,在 Xcode 中将 __NSMIN_IMPL__ 重命名为 MY__NSMIN_IMPL__(或者您将得到一个重复的宏警告),添加你省略的宏 - 再次重命名以避免冲突:

#define MY_MIN(A,B) MY__NSMIN_IMPL__(A,B,__COUNTER__)

并添加一些使用MY_MIN 的代码。现在在 Xcode 中选择菜单项 Product > Perform Action -> Preprocess "test.m" - 这将显示预处理器运行后的结果。如果您尝试使用不使用__NSX_PASTE____NSMIN_IMPL__ 版本,您将看到__COUNTER__ 未展开。

HTH

【讨论】:

  • 哦,使用 Preprocess 工具进行的精彩演示。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 2017-06-07
  • 2016-03-21
  • 1970-01-01
  • 1970-01-01
  • 2012-11-14
  • 1970-01-01
相关资源
最近更新 更多