9

我正在使用 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 个这样的警告阻塞了我的编译器输出。

为什么我会收到此警告,我该如何正确解决?

我对简单地抑制所有未使用的变量警告不感兴趣,因为我确实想获得合法的警告。

4

6 回答 6

16

在您的标题中进行声明,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)。链接器的任务是确保您确实在某处定义了它。

于 2013-02-18T23:50:53.847 回答
13

Clang 将允许您将警告标志推入和弹出“诊断”堆栈:“通过编译指示控制诊断”。您可以像这样包装某些代码:

#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 声明,并在另一个文件中定义变量。有关详细信息,请参阅引用另一个类的静态 NSString * const

正如dreamlax 指出的那样,您实际上收到了这些警告,因为每个导入您的标头的文件都获得了自己的static变量副本;当我提出上述#pragma技术时,我误解了您的要求。

于 2013-02-18T23:40:07.883 回答
4

制作你的常量const

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

(正如其他人指出的,extern在实现文件中使用和定义)

于 2013-02-18T23:45:21.757 回答
2

也许,与其将它们初始化为字符串文字,不如运行一个初始化函数,该函数从特定于语言环境的文件中加载这些值,以便错误出现在翻译的语言中。当您的初始化函数分配给该变量时,您的编译器可能会相信该变量需要存在才能使编译成功。

于 2013-02-18T23:51:11.263 回答
1

GCC(我假设是clang)不会警告未使用的常量。这里要注意的一个陷阱是指针必须是 const 指针,而不仅仅是指向 const 的指针;因此,要正确声明不会触发任何警告的未使用字符串常量,您需要:

const char * const myConst = "myConst";
于 2014-09-03T11:10:48.143 回答
0

您可以将所有静态变量声明移动到您各自的 .m 文件中。这应该消除所有那些“未使用的变量”警告。原因是静态变量仅限于文件级范围。

于 2013-05-21T23:35:52.217 回答