Interpreting C pre pre processor code

自古美人都是妖i 提交于 2021-02-16 14:54:26

问题


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:

  1. Why the whole #define statement is wrapped in ( ) ?
  2. Is #object a text replacement for what ever value was provided ?
  3. Why the requirement for @"" before the #object ?
  4. 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:

  1. Parenthesis in macros are used everytime when the expanded macro could do something unexpected. A typical example is:
    #define SUM(A, B) A + B
    SUM(1, 1) * 3 //the expected result is 6, the real result is 1 + 1 * 3 = 4 
    Adding parenthesis around every macro is a good programming convention to prevent this type of errors.
  2. #param is a stringification operator. It wraps the parameter in quotes - e.g., parameter value is converted to "value".
  3. The stringification operator creates a C string, which is an array of characters (char *). The author wanted a NSString *, 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.
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!