グローバル const 変数の定義 - C++ の extern を介したアクセス
-
21-12-2019 - |
質問
このトピックに関するいくつかの回答を読みましたが、まだわかりません:
C++ では、グローバル const 変数定義は自動的に行われます。 static
. 。ただし、extern を介して別の cpp ファイルからアクセスできます。
// module.cpp
const int i = 0;
そして
// main.cpp
extern const int i;
int main ()
{
if (i > 10)
return 0;
else
return 1;
}
なぜこれが可能なのでしょうか(別のモジュールから内部リンケージを使用してオブジェクトにアクセスする)。通常は定義する必要があります i
として extern const int i = 0
module.cpp に、明示的に グローバルだが非静的定数, 、 または?
それに比べて、これは不可能です。
// module.cpp
static int i = 0;
そして
// main.cpp
extern int i;
int main ()
{
i = 10; // but read-only access like (i > 10) would be possible!
return 0;
}
答えは次のとおりです。はい、他のモジュールから内部リンクされたオブジェクトにアクセスできますが、読み取り専用です(つまり常に const を使用します)。
編集:
申し訳ありませんが、間違いを犯しました:元のコードでは式を試しただけです 効果なし (どちらの例でも):
extern const int i; // or extern int i for second example
int main ()
{
i>10;
return 0;
}
プログラム フローやデータがこの式に依存しているかのように、同じように動作するのではないかと考えていましたが、実際にはそうではありませんでした。コンパイラはこの効果のない式を単に切り取っただけのようで、リンカにはそれが認識されません。それで、すべて大丈夫です:最初の例では i
確かに定義されなければなりません extern const int i = 0
module.cpp と 2 番目の例 i
にはまったくアクセスできません(効果のない表現でない限り)。コンパイラはVC++2010です。
編集2:
ただし、今ではなぜこれが可能なのか理解できません。
// module.cpp
extern const int i = 0;
そして
// main.cpp
int i = 99;
int main ()
{
bool b = i>10;
return 0;
}
i
両方の外部リンケージを持っています。しかし、エラーはありません。module.cpp で定義するとき int i = 0
, 、次にエラー (複数のシンボル)。なぜ?
解決
私にとって、それはコンパイラのバグのように見えます。定数変数 i が定義されていません。main.cpp でのみ宣言されています。module.cpp の変数 i に関しては、内部リンケージがあり、モジュールの外部からアクセスすることはできません。
元の投稿への追加と比較して、コンパイラはこの状況と何の共通点もありません。外部シンボルが重複していないかチェックするリンカです。1 つの変数に修飾子 const があり、もう 1 つの変数に修飾子がない場合、2 つの異なる変数があると判断したと思います。リンカがエラーを出すかどうかは実装定義だと思います。さらに、そのような状況でリンカーの動作を制御できるいくつかのオプションを含めることができます。