初始化一个大小定义为extern const的数组时遇到问题。 我一直遵循以下规则:全局变量应该在头文件中声明为extern,并且它们的相应定义应该在其中一个实现文件中,以避免变量重新声明错误。这种方法工作正常,直到我必须初始化一个数组,其大小被定义为extern const。 我得到一个错误,预计会有一个常量表达式。但是,如果我尝试为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 :(得分:16)
常量是外部的,因此它在另一个编译单元(.o
文件)中定义。因此编译器无法在编译时确定数组的大小;直到链接时间才知道常量的值是什么。
答案 1 :(得分:3)
好吧,它将变量视为 const qualified ,而不是常量表达式。
答案 2 :(得分:3)
因为它只是一个int
我会删除extern
并使其成为定义而不是声明。我说这个的原因是,即使这种方法在包含头文件的每个源文件中放置一个单独的整数实例,我想大多数编译器都会优化其使用。事实上,如果不这样做,编译器就不可能优化其使用,因此不会从简单的算术表达式中优化它。
由于它被声明为const
,它将具有内部链接,因此您不会通过这种方式获得任何多重定义的符号问题。
答案 3 :(得分:2)
我认为这里的问题是,如果将变量声明为extern,则允许它在不同的模块(.o文件)中,甚至在动态库(.dll / .so)中。这当然意味着编译器可能无法在编译时解析变量内容,从而拒绝使用需要const的值。
我的意见是,完全可以不在这里使用extern并直接在头文件中声明它,因为它是一个int值,无论如何在代码中的任何地方使用时都会内联。我通常只在使用字符串时才使用extern const,因为我想确保在运行时只生成一个字符串实例。