0

Let's review Clang's MIN macro through this article: Deep learning IOS development of macro. The final result is 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);\
        })

But I don't understand the need of defining __NSX_PASTE__. Wouldn't it be the same and more readable to use directly:

#define __NSMIN_IMPL__(A,B,L) ({\
        __typeof__(A) __a##L = (A);\
        __typeof__(B) __b##L = (B);\
        (__a##L < __b##L) ? __a##L : __b##L;\
        })
Cœur
  • 37,241
  • 25
  • 195
  • 267

1 Answers1

2

The simple answer is the __NSX_PASTE__ is required as without it the __COUNTER__ macro (not shown in the question but see the full source in the linked article, or look at the definition in Apple's NSObjCRuntime.h) will not be expanded. This is due to the weird and wonderful way the C Preprocessor works and how it handles stringification and concatenation, a good place to read how all this works is the GCC documentation on macros.

To see the results with and without the __NSX_PASTE__ put your above macros in a test file, say test.m, in Xcode renaming __NSMIN_IMPL__ to MY__NSMIN_IMPL__ (or you'll get a duplicate macro warning), add the macro you omitted - again renamed to avoid clashes:

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

and add some code which uses MY_MIN. Now in Xcode select the menu item Product > Perform Action -> Preprocess "test.m" - this will show you the result after the preprocessor has run. If you try it with your version of __NSMIN_IMPL__ which does not use __NSX_PASTE__ you will see __COUNTER__ is not expanded.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86