未定义的常量数组引用

时间:2012-05-30 12:34:43

标签: c++ arrays header linker const

a.cpp

const unsigned char whatever[123] = { /* ... */ };

A.H

extern const unsigned char whatever[123];

b.cpp

#include "a.h"
unsigned char x = whatever[0];
// error: undefined reference to 'whatever'

为什么我会收到未定义的引用错误?如果没有const,错误就会消失。

如何在多个翻译单元之间共享常量数组?

5 个答案:

答案 0 :(得分:10)

这是人们遇到的一个怪癖,只是你定义了一个a.h头文件,它声明了一个包含123个字符的const数组,并为它指定了外部链接。当它被包含在b.cpp文件中时,你基本上承诺它将在其他一些翻译单元中找到它。

但是,每个const变量都有一个黑暗的秘密 - 它被困在其定义的翻译单元中,因为它隐含地给出了静态链接。您承诺您的编译器whatever将在多个翻译单元之间共享,但它实际上只忠于一个翻译单元而不喜欢共享。而且,嗯,你知道其余的。

通过在实现文件中明确声明extern来解决。

答案 1 :(得分:4)

3.5/3

 A name having namespace scope (3.3.5) has internal linkage if it is the name of
 ...
 — an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage;
 ...

Vars喜欢

 const int x = 10;

隐式定义为“静态”。

要使它们非静态(因此非内部),请使用“.c”文件中的“extern”修饰符。

尝试使用

extern const unsigned char whatever[123] = { /* ... */ };

答案 2 :(得分:1)

const在c ++中默认具有静态(内部)链接,在.c文件中也使用extern const This是一个随机的SO线程,有更多信息。或谷歌“c ++中的链接”。

答案 3 :(得分:0)

在C ++中,const是一个编译时const,例如

const int cc = 100;
int a[cc];

我们可以使用const在C ++中定义数组,但不能在C中定义。 由于它是const,无法更改哪个值,因此不需要在多个文件之间共享它们。所以,说,const有内部联系。

答案 4 :(得分:0)

要解决此问题,a.cpp应该:

#include "a.h"

在定义whatever之前。

如果范围中没有先前的声明,则const unsigned char whatever[123] = {...};将具有内部链接。但是如果包含a.h,则定义与先前的声明匹配。标头使用外部链接定义whatever,定义与名称匹配。

正如其他人所提到的,您也可以将extern放在定义中,以便在忘记#include "a.h"时不会发生此错误。但是,最佳做法是包含声明我们试图公开定义的任何内容的标题。