从C++调用 NSLog:"Format string is not a string literal (potentially insecure)"



当我从C++调用NSLog时,Xcode抱怨传递给NSLog的格式字符串不是文本字符串。以下是触发警告的代码行:

NSLog(CFSTR("Leaking?"));

我不知道用C++编写NSString的任何方法,也没有看到可以在项目设置中关闭的相关警告。有没有一种方法可以在不触发此消息的情况下从C++调用NSLog?我使用的是Xcode 4.2.1。

编辑:这确实是C++代码。我通常避免使用Objective-C++,坚持使用Objective-C或普通的旧C++,因为没有关于哪些在Objective-CC++中有效,哪些无效的官方文档。我只发现了一些模糊的警告,例如STL的某些部分可能存在问题。我使用模板、STL和C++的其他"高级"功能,所以我想安全地使用它。

编辑#2,解决方案:我刚刚发现clang支持的警告标志比实际记录的要多得多。(从Xcode提供给我的一长串警告中应该可以明显看出。)我尝试了-Wno格式的非文本a la gcc,现在Xcode很高兴。

您所要做的就是编写@"this"来创建一个文本NSString对象。

因此,用NSLog(@"Leaking?");替换该行,您应该会没事的。

您可能需要使用扩展名.mm重命名文件,以确保它被编译为Objective-C++(Objective-C和C++的变体love child)。如果您不想这样做,可以在一个调用NSLog的小mm文件中创建一个包装函数,然后从C++代码中调用该函数。它看起来是这样的:

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

请注意,编译器给您带来痛苦的原因是,除了不可变的字符串文字(在编译时内容是已知的)之外,使用任何东西都是安全风险。否则,可以将格式字符串更改为包括不存在的参数的格式说明符(例如,%d)。如果发生这种情况,NSLog只会从堆栈中获取随机指针,可能会发生一些不好的事情。(有关更多信息,请参阅此问题。)

如果您正在调用NSLog,它是Foundation的一部分,那么您正在使用Objective-C。使用NSLog(@"Leaking?");并确保您的文件具有.mm扩展名,以明确您正在混合使用Objective-CC++

相关内容

最新更新