我正在使用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个这些警告堵塞了我的编译器输出。
为什么我收到此警告以及如何妥善解决?
我对简单地压制所有未使用的变量警告并不感兴趣,因为我确实希望得到合法的警告。
答案 0 :(得分:15)
在标题extern
中声明static
。你正在做的是为包含你的标题的每个翻译单元创建一个变量,这就是Clang警告你的原因,因为它是合法的未被使用的定义变量。 extern
关键字告诉编译器变量的定义是在其他地方找到的(它可能在同一个翻译单元中,也可能在另一个翻译单元中)。
在标题中,有:
// declare that the constant exists somewhere
extern NSString * const kErrorCannotDivideByZero;
在一个的.m
个文件中(通常是与标题名称相同的文件),请输入
// define the constant, i.e. this is where it exists
NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero";
声明变量extern
允许编译器确保您正确处理变量,即使它不知道它的定义位置(例如,您不能将其用作NSArray
)。链接器的作用是确保您在某处实际定义它。
答案 1 :(得分:12)
Clang允许您在“诊断”堆栈上推送和弹出警告标志:"Controlling diagnostics via pragmas"。您可以像这样包装某些代码:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero";
#pragma clang diagnostic pop
告诉Clang您知道这些没有被使用,在这个特定情况下这没关系。
顺便提一下,您可能不希望在导入到许多不同位置的文件中定义这些变量 - 这是导致链接器有关变量重定义的错误的好方法(尽管这只会发生在变量是全局链接的 - 声明/定义的没有 static
)。像这样的常量的通常模式是在标题中放置extern
声明,并在另一个文件中定义变量。有关详细信息,请参阅Referencing a static NSString * const from another class。
正如dreamlax指出的那样,您实际上是在收到这些警告,因为导入标题的每个文件都会获得自己的static
变量副本。当我提出上述#pragma
技术时,我误解了你的要求。
答案 2 :(得分:4)
制作常量const
:
static NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero";
(和其他人指出的那样,使用extern
并在实现文件中定义)
答案 3 :(得分:2)
也许,您可以运行一个初始化函数,而不是将它们初始化为字符串文字,该函数从特定于语言环境的文件加载这些值,以便错误以翻译语言显示。当您的初始化函数分配给该变量时,您的编译器可能会认为该变量需要存在才能使编译成功。
答案 4 :(得分:1)
const char * const myConst = "myConst";
答案 5 :(得分:0)
您可以将所有静态变量声明移动到相应的.m文件中。这应该消除所有那些“未使用的变量”警告。原因是静态变量仅限于文件级范围。