Intereting Posts
Неожиданный вывод в многопоточной программе fgets () Не игнорирует новую строку изменчивая переменная, использующая при создании приложения Как я могу сортировать массивы в массиве указателей в порядке убывания, используя сортировки пузырьков или сортировку сортировки? Коммуникация сокетов / сервера (AF_UNIX) Пересечение через рекурсивный список в C Как извлечь полуточные частоты из WAV-файла с использованием преобразований Фурье Как статические переменные с тем же именем в разных функциях, идентифицированных Системой? libcurl (linux, C) – Есть ли встроенный способ отправки POST / PUT запроса gzipped? Использование popen () для открытия программы в командной строке? Есть ли простая альтернатива Readline? Bison противоречивый тип для yyerror не может читать png-файл с помощью libpng Кто-нибудь знает причину, по которой переменные должны быть определены в верхней части функции Почему компилятор жалуется, когда я не делаю результат malloc?

Как использовать типизированные константы с предупреждениями «неиспользуемая переменная»?

Я использую Xcode 4.6, и у меня есть заголовочный файл, который содержит некоторые константы, которые я использую во всем моем коде. Я не хочу использовать директивы препроцессора, потому что я хочу, чтобы они были правильно напечатаны и таковы.

Например, у меня есть этот код в одном из моих файлов .h:

static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

и я использую его в соответствующем файле .m:

 [self showToast:kErrorCannotDivideByZero]; 

Я получаю предупреждение:

 /path/to/my/headerFile.h:32:18: Unused variable 'kErrorCannotDivideByZero' 

Я знаю, что это просто предупреждение, но у меня есть около 50 из этих предупреждений, засоряющих мой вывод компилятора.

Почему я получаю это предупреждение и как я могу его решить?

Меня не интересует просто подавление всех неиспользуемых переменных предупреждений, потому что я хочу получить законные.

Сделайте объявление в заголовке extern скорее static . То, что вы делаете, создает переменную для каждой единицы перевода, которая включает ваш заголовок, и именно поэтому Clang предупреждает вас, потому что это законно определенная переменная, которая не используется. Ключевое слово extern сообщает компилятору, что определение переменной находится где-то в другом месте (оно может находиться в одной и той же системе перевода или может быть в другом).

В своем заголовке:

 // declare that the constant exists somewhere extern NSString * const kErrorCannotDivideByZero; 

И в одном из ваших файлов .m (обычно тот, который имеет то же имя, что и заголовок), поместите

 // define the constant, ie this is where it exists NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

Объявление переменных extern позволяет компилятору обеспечить правильную обработку переменной, даже если она не знает, где она определена (например, вы не можете использовать ее как NSArray ). У компоновщика есть задача убедиться, что вы его где-то определили.

Clang позволит вам нажимать и выставлять предупреждающие флаги на «диагностический» стек: «Управление диагностикой через прагмы» . Вы можете обернуть некоторые fragmentы кода следующим образом:

 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; #pragma clang diagnostic pop 

сказать Клану, что вы знаете, что они не используются, и это нормально в данном конкретном случае.

Кстати, вы не можете определять эти переменные в файле, который импортируется во многие разные места – это хороший способ вызвать ошибки компоновщика в отношении переопределения переменных (хотя это произойдет только в том случае, если переменная была глобально связана – объявлена ​​/ определена без static ). Обычным шаблоном для таких констант является размещение объявления extern в заголовке и определение переменной в другом файле. Подробнее см. Ссылку на статический NSString * const из другого classа .

Как отметил dreamlax, вы действительно получаете эти предупреждения, потому что каждый файл, который импортирует ваш заголовок, получает свою собственную копию static переменной; когда я предложил технику #pragma выше, я не понимал, о чем вы просите.

Сделайте константы const :

 static NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero"; 

(и, как указывали другие, используйте extern и определите в файле реализации)

Возможно, вместо того, чтобы инициализировать их для строковых литералов, вы можете запустить функцию инициализации, которая загружает эти значения из файла, специфичного для локали, чтобы ошибки были переведены на язык перевода. Когда ваша функция инициализации назначает эту переменную, ваш компилятор может испытывать соблазн полагать, что переменная должна существовать для успешного компиляции.

GCC (и я предполагаю, что clang) не предупреждает о неиспользуемых константах. Одна из ловушек, на которую нужно обратить внимание, заключается в том, что указатели должны быть указателями констант, а не только указателями на const; поэтому для правильного объявления неиспользуемой строковой константы, которая не будет вызывать никаких предупреждений, вам необходимо:

 const char * const myConst = "myConst"; 

Вы можете перенести все объявления статической переменной в свой .m-файл. Это должно забрать все эти предупреждения «неиспользуемые переменные». Причина в том, что статические переменные ограничены областью уровня файла.