web-dev-qa-db-ja.com

なぜ「extern const int n;」になるのですか。期待どおりに動作しませんか?

私のプロジェクトは2つのソースファイルのみで構成されています。

a.cpp:

const int n = 8;

b.cpp:

extern const int n;

int main()
{
    // error LNK2001: unresolved external symbol "int const n" (?n@@3HB)
    int m = n; 
}

私はそれを機能させるためにいくつかの方法があることを知っています。ただし、なぜ機能しないのでしょうか。

27
xmllmx

これは、デフォルトでconstが内部リンケージを意味するため、「定義」は、それが表示される翻訳単位の外には表示されないためです。

この場合、断然最善の解決策は、宣言(extern int const n;)をヘッダーファイルに含め、両方に含めますa.cppおよびb.cpp。リンケージは、コンパイラーが認識する最初の宣言によって決定されるため、a.cppは正しい(外部)リンケージになります。

または、定義でリンケージを強制できます。

extern int const n = 8;

externにもかかわらず、これはまだ定義です。クラス定義の外に初期化子があるものはすべて定義です。

50
James Kanze

C++のconst変数とconstexpr変数は、externも宣言されていない場合(定義または前の宣言で)。

Cではそうではありません(まあCはconstexprをしていません)ので、コードは有効です。さらに、定義にexternを付けることができます。

したがって、CとC++の両方であるコードを作成する場合(および2つの宣言は、Jamesが指摘したのと同じヘッダーから取得する必要があります):

// a.cpp
extern const int n;
const int n = 8;

// b.cpp
extern const int n;

int main()
{

    int m = n; 
}

そうでない場合

// a.cpp
extern const int n = 8;

も可能です

6
AProgrammer

To share a const object among multiple files, you must define the variable as extern.

To define a single instance of a const variable, we use the keyword extern on both its definition and declaration(s):

これらのルールから、定義にexternキーワードを追加するだけです。あなたはすでに宣言にそれを持っています。

2
Arpit

A.cppでexternと宣言し、b.cppでexternなしで使用します。

extern const int n ;

a.cpp

#include "a.h"
...
const int n= 8

b.cpp:

#include "a.h"
...


int main()
{        
    int m = n; 
}
2
Gjordis

ここでの他の回答でうまくいかない場合は、定義が別の名前空間にある可能性があります...コンパイルが成功し、undefined symbolリンカーエラーが発生する場合:

  • 未定義のシンボルの名前空間を確認してください。これがextern const int n宣言の有効な名前空間です。
  • それがconst int n = 8定義を作成する有効な名前空間であることを確認してください。
1
einpoklum