Friday, April 3, 2015

Preprocessor Abuse and Optional Parentheses

Mike Ash:

While coming up with macros that would justify this [UNPAREN()] construct, I built a nice dispatch_once macro for making lazily-initialized constants. Here it is:

#define ONCE(type, name, ...) \
    UNPAREN(type) name() { \
        static UNPAREN(type) static_ ## name; \
        static dispatch_once_t predicate; \
        dispatch_once(&predicate, ^{ \
            static_ ## name = ({ __VA_ARGS__; }); \
        }); \
        return static_ ## name; \
    }

Here’s an example use:

ONCE(NSSet *, AllowedFileTypes, [NSSet setWithArray: @[ @"mp3", @"m4a", @"aiff" ]])

Then you can call AllowedFileTypes() to obtain the set, and it's efficiently created on demand. In the unlikely event that the type contains a comma, you can add parentheses and it will still work.

Comments RSS · Twitter

Leave a Comment