Bug in Clang function-like macro parsing with Objective C variadic method call?

195 Views Asked by At

Consider the following call:

NSString* localized = NSLocalizedString([NSString stringWithFormat:@"Hello %@", @"World"], @"");

What is wrong with it? I see nothing inherently wrong, yet the compiler/preprocessor complains that too many parameters were passed to it. On the other hand, the following two compile:

Explicit variable:

NSString* string = [NSString stringWithFormat:@"Hello %@", @"World"];
NSString* localized = NSLocalizedString(string, @"");

Wrap in brackets:

NSString* localized = NSLocalizedString(([NSString stringWithFormat:@"Hello %@", @"World"]), @"");

Looks like the preprocessor/compiler incorrectly parses the , character.

I am getting this in Xcode 7 beta 6, so it might be a new bug in the Clang toolchain.

1

There are 1 best solutions below

8
On

This isn't a bug, it is how the C pre-processor works. From the C Standard:

The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments.

So commas delimit macro arguments unless they are inside matching inner parentheses - this is your "wrap in brackets" variation works. C doesn't talk about matching brackets, [ & ], only parentheses, ( & ), so your first example has three macro arguments: [NSString stringWithFormat:@"Hello %@", @"World"] and @"". Preprocessing takes place before syntax analysis, so the fat that the first two arguments don't make syntactic sense in (Objective-)C doesn't matter.

HTH