Подтвердить что ты не робот

__unused флаг поведение/использование (GCC с Objective-C)

Я только что узнал о знаке __unused, который можно использовать при компиляции с GCC, и чем больше я узнаю об этом, тем больше вопросов у меня есть...

Почему это компилируется без предупреждения/ошибки? Кажется странным, что я конкретно говорю компилятору, что не буду использовать переменную, а затем, когда я ее использую, все происходит как обычно.

- (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;
4b9b3361

Ответ 1

Макрос __unused (который фактически расширен до атрибута __attribute__((unused)) GCC) только говорит компилятору "не предупреждайте меня, если я не использую эту переменную".

unused: Этот атрибут, привязанный к переменной, означает, что переменная должна быть, возможно, не использована. GCC не создает предупреждение для этой переменной. (Источник: gnu.gcc.org doc)

Таким образом, этот атрибут GCC должен избегать предупреждения, когда вы не используете переменную, и НЕ запускать один, когда используете переменную, которую вы заявили как неиспользованный.


Что касается размещения атрибута до или после имени переменной в вашем последнем примере, оба они принимаются и эквивалентны в вашем случае: компилятор просто снисходителен к этому месту размещения для целей совместимости (так же, как вы также можете написать как const int i или int const i)

Для совместимости с существующим кодом, написанным для версий компилятора, которые не применяли атрибуты для вложенных деклараторов, допускается некоторая слабость при размещении атрибутов (Source: gnu. gcc.org doc)

Ответ 2

Как и в 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 рекомендует первый синтаксис. (информация была частично взята из этого ответа)

Но есть разница между:

__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] мой личный опыт, поскольку он не оставляет никакой двусмысленности.

Последние три решения приемлемы, но сбивают с толку, на мой взгляд. (информация была частично взята из этого ответа)