Вызов NSLog из C ++: «Формат строки не является строковым литералом (потенциально небезопасным)» - PullRequest
5 голосов
/ 20 марта 2012

Когда я вызываю NSLog из C ++, Xcode жалуется, что строка формата, переданная NSLog, не является литеральной строкой.Вот строка кода, которая вызывает предупреждение:

NSLog(CFSTR("Leaking?"));

Я не знаю ни одного способа кодирования литеральной строки NSString в C ++, и я не вижу соответствующего предупреждения, которое можно отключить внастройки проекта.Есть ли способ вызвать NSLog из C ++, не вызывая это сообщение?Я использую Xcode 4.2.1.

Редактировать: Это действительно код C ++.Я обычно избегаю Objective-C ++, придерживаясь либо Objective-C, либо старого C ++, потому что нет официальной документации о том, что работает в Objective-C ++, а что нет.Я нашел только смутные предупреждения о том, что (например) могут быть проблемы с некоторыми частями STL.Я использую шаблоны, STL и другие «продвинутые» функции C ++, поэтому я хочу быть осторожнее.

Правка # 2, решение: я только что понял, что clang поддерживает гораздо больше флагов предупреждений, чемна самом деле документально.(Это должно было быть очевидно из длинного списка предупреждений, которые мне предлагал Xcode.) Я попробовал -Wno-format-nonliteral a la gcc, и теперь Xcode доволен.

Ответы [ 2 ]

7 голосов
/ 20 марта 2012

Все, что вам нужно сделать, это написать @"this" для создания литерального объекта NSString.

Так что замените эту строку на NSLog(@"Leaking?");, и все будет в порядке.

Возможно, вам придется переименовать ваш файл с расширением .mm, чтобы убедиться, что он скомпилирован как Objective-C ++ (мутант-потомок Objective-C и C ++). Если вы не хотите этого делать, вы можете создать функцию-обертку в крошечном mm-файле, который вызывает NSLog, а затем вызвать эту функцию из вашего кода C ++. Это будет выглядеть так:

void MyNSLog(const char *message)
{
    NSLog(@"%s", message);
}

Обратите внимание, что причина, по которой компилятор доставляет вам горе, заключается в том, что использование чего-либо, кроме неизменяемого строкового литерала (где содержимое известно во время компиляции), представляет угрозу безопасности. В противном случае строка формата может быть изменена для включения спецификаторов формата (например, %d) для параметров, которых там нет. Если это произойдет, NSLog просто получит случайные указатели из стека, и может случиться что-то плохое. (См. этот вопрос для получения дополнительной информации.)

4 голосов
/ 20 марта 2012

Если вы звоните NSLog, который является частью Foundation , то вы используете Objective-C.Используйте NSLog(@"Leaking?"); и убедитесь, что ваш файл имеет расширение .mm, чтобы было ясно, что вы смешиваете Objective-C и C++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...