8

a.cpp

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

ああ

extern const unsigned char whatever[123];

b.cpp

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

未定義の参照エラーが発生するのはなぜですか?がないとconst、エラーはなくなります。

複数の変換ユニット間で定数の配列を共有するにはどうすればよいですか?

4

5 に答える 5

13

これは、人々が遭遇する癖の1つです。これは、123文字のconst配列を宣言するahヘッダーファイルを定義し、それに外部リンケージを割り当てただけの問題です。それがb.cppファイルに含まれている場合、基本的に、他の変換ユニットで見つかるコンパイラーを約束します。

しかし、すべてconstの変数には暗い秘密があります。暗黙的に静的なリンクが与えられているため、定義している変換ユニット内に閉じ込められています。コンパイラwhateverは複数の翻訳ユニット間で共有されると約束しましたが、実際には1つの翻訳ユニットに忠実であり、共有することは好みません。そして、まあ、あなたは残りを知っています。

extern実装ファイルに明示的に記載することで解決します。

于 2012-05-30T13:00:32.313 に答える
5
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;
 ...

のような変数

 const int x = 10;

'static'として暗黙的に定義されます。

それらを非静的(したがって非内部)にするには、「。c」ファイルで「extern」修飾子を使用します。

使ってみてください

extern const unsigned char whatever[123] = { /* ... */ };
于 2012-05-30T12:41:15.117 に答える
1

constには、デフォルトでc ++の静的(内部)リンケージがあります。.cファイルでもexternconstを使用してください。
これは、より多くの情報を持つランダムなSOスレッドです。またはグーグル「c++のリンケージ」。

于 2012-05-30T12:40:52.933 に答える
1

これを修正するには、次のようにするa.cpp必要があります。

#include "a.h"

の定義の前whatever

スコープ内に以前の宣言がない場合は、const unsigned char whatever[123] = {...};内部リンクがあります。ただし、a.hが含まれている場合、定義は前の宣言と一致します。ヘッダーはwhatever外部リンケージで定義され、定義は名前と一致します。

他の人が述べたように、定義を入れることもできるexternので、忘れてもこのエラーは発生しません#include "a.h"。ただし、公に定義しようとしているものを宣言するヘッダーを含めることは、依然としてベストプラクティスです。

于 2018-02-08T20:34:36.503 に答える
0

C ++では、constはコンパイル時のconstです。たとえば、

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

constを使用してC++で配列を定義することはできますが、Cでは定義できません。値を変更できないconstであるため、複数のファイル間で配列を共有する必要はありません。つまり、constには内部リンクがあります。

于 2012-05-30T14:03:46.850 に答える