问题
Given #define LOG_OBJECT(object) (NSLog(@"" #object @" %@ %@:%d”, [object description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
The statement LOG_OBJECT(self);
will produce:
2014-07-18 17:43:30.041 FrogCamera[12484:2144843] self ViewController.m:20
I wish to understand how the preprocessor code works. How can I see the statement that the pre processor produced?
Specifically:
- Why the whole #define statement is wrapped in
( )
? - Is
#object
a text replacement for what ever value was provided ? - Why the requirement for
@""
before the#object
? - Namely how is
@“” #object @“ %@ %@:%d”
is transformed to@"self %@ %@:%d"
?
Here’s a usage example:
@interface ViewController ()
#define LOG_OBJECT(object) (NSLog(@"" #object @" %@ %@:%d", [object description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
LOG_OBJECT(self);
// = 2014-07-18 17:48:19.439 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:20
(NSLog(@"self %@ %@:%d", [self description], [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__));
// = 2014-07-18 17:48:19.440 FrogCamera[12597:2151087] self <ViewController: 0x79755000> ViewController.m:21
}
@end
See GlobalUtilities.h for origin of LOG_OBJECT statement.
回答1:
This is rather simple:
- Parenthesis in macros are used everytime when the expanded macro could do something unexpected. A typical example is:
Adding parenthesis around every macro is a good programming convention to prevent this type of errors.#define SUM(A, B) A + B SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4
#param
is a stringification operator. It wraps the parameter in quotes - e.g., parametervalue
is converted to"value"
.- The stringification operator creates a C string, which is an array of characters (
char *
). The author wanted aNSString *
, that's why he is adding an@
in the beginning. Note that@"aaa" "bbb"
is equivalent to@"aaabbb"
(this feature enables us to split strings over multiple lines). However, this is not very elegant. Using a%s
would make it a bit simpler. - It is converted only to
@"" "self" @" %@ %@:%d"
. The compiler considers consecutive strings as one string.
回答2:
If you want to see what the preprocessor macros expand to, with the file open click the Product menu, then Perform Action->PreProcess "ViewController.m". This will let you see what the expanded source, with the macros replaced, looks like. For more details on what you can do with macros, see the Apple Docs
来源:https://stackoverflow.com/questions/24828542/interpreting-c-pre-pre-processor-code