让我们通过本文审核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;\
})
答案 0 :(得分:2)
简单的答案是__NSX_PASTE__
是必需的,因为没有__COUNTER__
宏(问题中未显示,但请参阅链接文章中的完整来源,或查看Apple中的定义&#39} ; s NSObjCRuntime.h
)不会被扩展。这是因为C预处理器工作的奇怪和奇妙的方式以及它如何处理 stringification 和 concatenation ,这是一个阅读所有这些工作原理的好地方{{3} }。
使用和不使用__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&gt;执行操作 - &gt;预处理&#34; test.m&#34; - 这将在预处理器运行后显示结果。如果您使用不使用__NSMIN_IMPL__
的{{1}}版本进行试用,则会看到__NSX_PASTE__
未展开。
HTH