36

我刚刚了解了使用 GCC 编译时可以使用的 __unused 标志,我了解的越多,我的问题就越多......

为什么编译时没有警告/错误?我特意告诉编译器我不会使用变量,这似乎很奇怪,然后当我使用它时,一切都照常进行。

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self foo:0];
}

- (void)foo:(NSInteger)__unused myInt
{
    myInt++;
    NSLog(@"myInt: %d", myInt);  // Logs '1'
}

另外,以下两个方法签名有什么区别?

- (void)foo:(NSInteger)__unused myInt;

- (void)foo:(NSInteger)myInt __unused;
4

2 回答 2

82

宏(__unused实际上扩展为__attribute__((unused))GCC 属性)仅告诉编译器“如果我不使用此变量,请不要警告我”。

unused:附加到变量的此属性意味着该变量可能未被使用。GCC 不会对此变量产生警告。来源:gnu.gcc.org 文档

因此,此 GCC 属性是为了避免在您不使用变量时出现警告,而不是在使用您声称未使用的变量时触发警告。


关于在上一个示例中将属性放在变量名之前或之后,两者都被接受并且在您的情况下是等效的:出于兼容性目的,编译器对该位置很宽容(就像您也可以同时编写const int ior int const i

为了与为未在嵌套声明符上实现属性的编译器版本编写的现有代码兼容,在放置属性时允许有一些松懈来源:gnu.gcc.org doc

于 2013-11-01T22:24:34.477 回答
11

从 Xcode 7.3.1 开始,目前没有区别:

- (void)foo:(NSInteger)__unused myInt;// [syntax 1]
- (void)foo:(NSInteger __unused)myInt;// [syntax 2]
- (void)foo:(__unused NSInteger)myInt;// [syntax 3]

但以下不起作用:

- (void)foo:(NSInteger)myInt __unused;// [doesn't work]

对于这方面的用法,Apple 建议使用 first syntax。(信息部分来自这个答案

但两者之间有区别:

__unused NSString *foo, *bar;  // [case a] attribute applies to foo and bar
NSString *foo __unused, *bar;  // [case b] attribute applies to foo only

NSString * __unused foo, *bar; // [case c] attribute applies to foo only
NSString __unused *foo, *bar;  // [case d] attribute applies to foo and bar
CFStringRef __unused foo, bar; // [case e] attribute applies to foo and bar

如果我们想__unused应用于所有,语法 [a] 是我个人最好的,因为它没有歧义。

如果我们想__unused应用于其中一个,语法 [b] 是我个人最好的,因为它没有歧义。

后三种解决方案是可以接受的,但在我看来令人困惑。(信息部分来自这个答案

于 2016-04-25T04:28:59.587 回答