__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;
Ответы
Ответ 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] мой личный опыт, поскольку он не оставляет никакой двусмысленности.
Последние три решения приемлемы, но сбивают с толку, на мой взгляд. (информация была частично взята из этого ответа)