28

1 つの定義規則により、C または C++ ではグローバル変数の複数定義は許可されません。ただし、C++ では、const グローバル変数を複数のコンパイル ユニットでエラーなしで定義できます。これは C と同じではありません。

Cでは許可されていないのに、C++では許可されているのはなぜですか? C++ では、C と比較して、const グローバルの使用法と動作が非 const グローバルとこのように異なるのはなぜですか? const に関して、C++ と C のカバーの下で何が起こっていますか?

たとえば、これは C++ では許可されていますが、C では間違っています。

// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;
int main()
{
    cout << Foo << endl;
    return 0;
}

これは C では問題ありませんが、C++ では問題があります。

// Foo.cpp
const int Foo = 99;

// Main.cpp
extern const int Foo;
int main()
{
    cout << Foo << endl;
    return 0;
}
4

6 に答える 6

28
// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;

const名前空間スコープの変数には内部リンケージがあります。したがって、これらは基本的に 2 つの異なる変数です。再定義はありません。

@David のコメントから、3.5/3 [basic.link]:

名前空間スコープ (3.3.5) を持つ名前は、それが次の名前である場合、内部リンケージ
を持ちます — 明示的に static と宣言されたオブジェクト、参照、関数、または関数テンプレート、または—明示的に const と宣言され、明示的に宣言されていない
オブジェクトまたは参照extern も、以前に外部リンケージを持つと宣言されていません。または
— 無名共用体のデータ メンバー。


2 番目のケースでは、これを行う必要があります (正しい方法):

//Foo.h
extern const int Foo; //use extern here to make it have external linkage!

// Foo.cpp
#include "Foo.h"
const int Foo = 99; //actual definition goes here

// Main.cpp
#include "Foo.h"
int main()
{
   cout << Foo << endl;
}
于 2011-05-30T08:21:17.800 に答える
7

私はあなたがこれを可能にする特定の言語規則ではなく、理論的根拠を求めていると思います。

これの理論的根拠は、const変数をはるかに使いやすくすることです。これは、の1つの一般的な使用法の型付き​​置換を提供します#define

代わりに、1つの定義をどこに置くかを気にすることなく、まったく同じ方法で#define MAX_COUNT 211使用できます。たとえば、共有ヘッダーファイルです。const int max_count = 211;

オブジェクトの値を合法的に変更することはできないconstため、1つのオブジェクトと同じ値を持つ複数のオブジェクトの間に目に見える違いはありません。

オブジェクトの定義をヘッダーファイルに入れることができるのでconst、コンパイラがコンパイル段階で値を直接使用するのは簡単です。そのような最適化をリンク時の修正に遅らせる必要はありません。

于 2011-05-30T08:38:19.160 に答える
6

基本的に、C++ では、const、非ローカル変数は本物の定数式、または constexpr です。これにより、TMP など、多くのことが可能になります。

const int five = 5;
int main() {
    int x[five];
    std::array<int, five> arr;
}

C では、これらは変更できない単なる変数です。あれは、

const int five = 5;
int main() {
    int x[five]; // Technically, this is a variable length array
}

とまったく同等です

int five = 5;
int main() {
    int x[five];
}

事実上、C++ はある種のconst変数を新しいカテゴリ に昇格させますconstexprが、C ではこれは存在せず、たまたま変更できない変数にすぎません。

于 2011-05-30T08:59:44.960 に答える
3

const は実際には外部シンボルを生成しないようです。

于 2011-05-30T08:22:53.113 に答える
-1

アメリカ人は COLOR と綴るのに、なぜイギリス人は COLOUR と綴るのですか?

これらは同じベースの 2 つの異なる言語ですが、同じルールはありません。

C と C++ は同じです。違いがなければ、どちらも同じものと呼ばれるでしょう。

于 2012-05-04T13:00:01.543 に答える
-3

私の回避策は次のように宣言していました:

static classfoo foo;

私の状況ではうまくいきました。

于 2013-10-22T02:32:48.327 に答える