声明一个大小为extern const的数组

12

我在初始化一个大小被定义为extern 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;
}

你可以使用四个空格缩进代码以进行格式化。 - Thomas
4个回答

16

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


3

它将变量视为const限定符,而不是常量表达式


3

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

由于它被声明为const,因此它将具有内部链接,因此通过这种方式进行操作,您将不会遇到任何重复定义符号问题。


谢谢。我现在明白了。但是,为什么这种方法对于常量指针不起作用呢?如果我在头文件中定义const char* FILE_NAME = "Log.txt",并在多个源文件中包含该头文件,我仍然会得到链接错误。但是,我对于语句const char FILE_NAME[] = "Log.txt"没有错误。 - psvaibhav
@psvaibhav:那样行不通,因为const char*声明指针为指向常量的指针,而不是常量指针。你需要在*后面加上一个额外的const来使指针本身成为常量,即const char*const - Troubadour

2
我认为这里的问题在于,如果将变量声明为extern,则允许它位于不同的模块(.o文件)甚至动态库(.dll/.so)中。当然,这意味着编译器可能无法在编译时解析变量内容,从而拒绝在需要const值的地方使用该值。
我的观点是,在此处不使用extern并直接在头文件中声明它是完全可以的,因为它只是一个int值,无论何时在代码中使用都将被内联。我通常仅在使用字符串时使用extern const,因为我希望确保在运行时仅生成一个字符串实例。

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