Objective-C错误:初始化元素不是常量。

10
为什么编译器在提供的代码上给我以下错误消息:“初始化程序元素不是常量”?相应的C/C++代码在gcc下编译完美无瑕。
#import <Foundation/Foundation.h>

const float a = 1;
const float b = a + a; // <- error here

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // insert code here...
    NSLog(@"Hello, World!");
    [pool drain];
    return 0;
}

你知道Objective-C也是在gcc下编译的吗? - hhafez
你可以移除所有的Objective-C相关内容,将其编译为C语言,但是你会得到同样的错误。 - Chuck
2
但是你也可以删除所有的Objective-C内容,保存到main.c文件中,并使用gcc main.c进行编译,它将按预期工作。(至少对我来说是这样) - Przemyslaw Zych
3个回答

12

只有在除文件作用域之外的其他地方出现 const float 声明语句时,该代码才能正确编译。

这似乎是标准的一部分。重要的是,所有在文件作用域声明的变量都必须使用常量表达式进行初始化,不能使用涉及常量变量的表达式。

您正在使用另一个对象的值对浮点数'b'进行初始化。 在C语言中,任何对象的值(包括const限定的对象)都不是常量表达式。


你能解释一下为什么吗?谢谢,我很感兴趣。 - hhafez
2
@hhafez — 在这种情况下,'b'并没有被初始化为另一个对象,而是被初始化为另一个基本类型。然而,它们都被声明为'const',而'b'依赖于'a'的值,这在标准中是不合法的。 - Quinn Taylor
你能解释一下“只有当const float语句出现在文件范围之外时,才能正确编译”的部分吗?这是什么意思? - Olie

4

@dreamlax 是正确的,你不能有一个常量声明其初始化取决于另一个(常量)变量。如果你需要一个变量依赖于另一个变量,我建议创建一个你可以视为常量的变量,并仅初始化一次。有关详细信息,请参见以下 SO 问题:


1

我这台机器上没有安装Xcode,所以无法尝试我的示例,

但你能试试吗?

#define A (1) 
#define B (A + A)

const float a = A;
const float b = B;

你的第二个解决方案会产生相同的错误... 你不能只是将一个变量强制转换为字面值。 - Jason Coco
删除了我的第二个解决方案(只留下了第一个)。 - hhafez
3
请注意,#define表达式是“预处理器指令”,这意味着它们在编译器开始编译之前就被替换为代码。如果表达式有效,这是因为在编译时你得到了“const float a = (1);”和“const float b = ((1) + (1));”。总体来看,这是相当无意义的。 - Quinn Taylor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接