2009-11-07 188 views
11

初始化大小定义为extern const的数组时,出现问题。 我一直遵循的规则是全局变量应该在头文件中声明为extern,并且它们的相应定义应该放在其中一个实现文件中,以避免可变的重新声明错误。这种方法运行良好,直到我不得不初始化一个数组,其大小定义为一个extern const。 我收到一个错误,表示一个常量表达式。但是,如果我试图给const变量赋值,编译器会正确地抱怨一个值不能被赋值给一个常量变量。这实际上证明编译器确实将该变量看作一个常量。那么为什么在尝试声明相同大小的数组时报告了错误?声明大小声明为extern的数组const

有没有什么办法避免这种情况,而不使用#define?我也想知道这个错误的原因。

Package.h:

#ifndef PACKAGE_H 
#define PACKAGE_H 

extern const int SIZE; 

#endif 

Package.cpp:

#include "Package.h" 

const int SIZE = 10; 

Foo.cpp中:

#include "Package.h" 

int main() 
{ 
    // SIZE = 5; // error - cannot assign value to a constant variable 
    // int Array[SIZE]; // error - constant expression expected 
    return 0; 
} 
+0

您可以使用四个空格缩进代码以对其进行格式化。 – Thomas 2009-11-07 14:16:28

回答

16

该常量是外部的,因此它在另一个编译单元(.o文件)中定义。因此,编译器无法在编译时确定数组的大小;直到链接时间才知道常数的值是多少。

3

好,它看到变量,常量合格,不作为的常数表达

2

我相信这里的问题是,如果你声明你的变量为extern,它可以在不同的模块(.o文件)中,甚至在动态库(.dll/.so)中。这当然意味着,编译器可能无法在编译时解析变量内容,从而拒绝在需要const的地方使用该值。

我的意见是,在这里完全可以不使用extern并直接在头文件中声明它,因为它是一个int值,无论如何将在代码中的任何位置使用内联。我通常只在使用字符串时才使用extern const,因为我想确保在运行时只生成一个字符串实例。

3

因为它只是一个int我会删除extern并将其定义为一个定义而不是声明。我这样说的原因是,即使这种方法在包含头文件的每个源文件中放置了一个单独的整数实例,我想大多数编译器都会优化它的使用。事实上,编译器不可能优化它的使用,如果不这样做,它不会从简单的算术表达式中优化出来。

由于它被宣布为const它将具有内部链接,因此您不会通过这种方式获得任何多重定义的符号问题。

+0

谢谢。我想我现在明白了。但是,为什么这种方法不适用于const指针。如果我在头文件中定义了const char * FILE_NAME =“Log.txt”并将头文件包含在多个源文件中,我仍然会收到链接错误。我没有听到const char FILE_NAME [] =“Log语句的错误。txt“ – psvaibhav 2009-12-06 14:13:22

+0

@psvaibhav:这不起作用,因为'const char *'声明指针是一个指向const的指针,而不是一个常量指针,你需要的是'*'后面的一个额外的'const'指针本身的常量,例如'const char * const' – Troubadour 2009-12-06 22:29:40