可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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'
Why do I get an undefined reference error? Without the const
, the error goes away.
How do I share an array of constants among multiple translation units?
回答1:
This is one of the quirks people run into, it's simply a matter that you've defined an a.h header file which declares a const array of 123 chars, and assigned it external linkage. When it is included into the b.cpp file, you're basically promising the compiler it's going to find in some other translation unit.
But, every const
variable has a dark secret - it's trapped inside its defining translation unit because it is implicitly given static linkage. You promised your compiler whatever
will be shared across multiple translation units, but it is actually loyal to just one translation unit and doesn't like to be shared. And, well, you know the rest.
Resolve by explicitly stating extern
in the implementation file.
回答2:
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 like
const int x = 10;
are defined implicitly as 'static'.
To make them non-static (thus non-internal), use the 'extern' modifier in ".c" file.
Try using
extern const unsigned char whatever[123] = { /* ... */ };
回答3:
const has static (internal) linkage by default in c++, use extern const in your .c file as well.
This is a random SO thread that has more info. Or google "linkage in c++".
回答4:
in C++, the const is a compiling-time const, for example,
const int cc = 100;
int a[cc];
we can use const to define the array in C++, but can't in C.
Since it is const, which value can't be changed, it doesn't require to share them between multiple files. So, to say, const has internal linkage.
回答5:
To fix this, a.cpp
should do:
#include "a.h"
before the definition of whatever
.
If there is no previous declaration in scope then const unsigned char whatever[123] = {...};
would have internal linkage. But if a.h
is included, then the definition matches the previous declaration. The header defines whatever
with external linkage, and the definition matches the name.
As mentioned by others you could also put extern
in the definition, so that this error doesn't occur if you forget to #include "a.h"
. But it is still best practice to include the headers that declare anything we're trying to define publicly.