constがCではないのに、なぜC ++で内部リンケージを意味するのですか?


82

件名を参照してください。彼らは何を考えていましたか?

更新:混乱を避けるために、「静的」から「内部リンケージ」に変更されました。

例を挙げると...以下をファイルに入れます。

const int var_a = 1;
int var_b = 1;

...そしてg++ -c test.cppエクスポートのみでコンパイルしますvar_b

回答:


112

私はあなたが意味すると信じています

constがC ++の内部リンケージを意味するのはなぜですか

名前空間スコープでconstオブジェクトを宣言すると、内部リンケージがあるのは事実です。

付録C(C ++ 11、C.1.2)は理論的根拠を示しています

変更:明示的にconstとして宣言され、明示的にexternとして宣言されていないファイルスコープの名前には内部リンケージがありますが、Cでは外部リンケージになります

理論的根拠: constオブジェクトはC ++でコンパイル時の値として使用できるため、この機能はプログラマーに各constに明示的な初期化値を提供するように促します。この機能により、ユーザーはconstオブジェクトを多くのコンパイルユニットに含まれるヘッダーファイルに入れることができます。


非constグローバルオブジェクトも初期化できるようですが、なぜ標準では内部リンクが提供されないのですか?
Yong Li

13

litbが言ったように、constオブジェクトにはC ++の内部リンケージがあります。これは、次のように使用することを目的としているためです。

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];

6

constとstaticは、CとC ++の両方で直交する概念です。

このconstキーワードは、変数が式の左辺値として表示されないようにコンパイラーに指示します。つまり、基本的に読み取り専用にします。

Cでは、staticキーワードには、適用対象に応じていくつかの用途があります。関数の変数に適用される場合、変数が関数のローカルスコープに格納されていないが、関数の呼び出し全体でアクセス可能であることを示します。グローバル変数または関数に適用すると、特定のファイルにのみアクセスできるようになります。つまり、コンパイルユニット内でのみアクセスできます(宣言されていない場合extern)。

C ++では、staticキーワードをクラス定義内で使用して、各インスタンスに対してローカルではなく、クラスのすべてのインスタンス間で変数または関数を共有できます。さらに、C ++の静的クラス関数は、そのクラス(またはアクセスできるクラス)の静的変数にのみアクセスできます。現在、C ++constでは、明示的に宣言されていない限り、メンバーにコンパイルユニットへの内部リンクを提供しexternます。これはあなたが参照しているものかもしれません。これにより、ヘッダーファイルを使用して、コンパイル時定数をユニット間で共有できます。ただし、メンバーは実際には静的ではなく、定数は参照される各場所にコンパイルされることに注意してください。


6

C&C ++では、静的という用語には複数の意味があります(リンケージとストレージを管理できます)StroustrupのD&Eを読んで、彼の論理的根拠を理解する必要があります-しかし、変数を名前空間スコープでconstとして宣言すると、自動的に内部リンケージがあります- Cでは、静的に宣言して、内部リンケージを強制する必要があります。

もちろん、C ++では、リンケージを制御するための静的な使用は非推奨になりました。匿名の名前空間を使用して、C ++の内部リンケージをシミュレートできます。

C ++のconst変数は、プリプロセッサ定数を置き換えることになっています。プリプロセッサ定数は、それらを定義するファイルでのみ表示されるため、同様に、constは、変数を定義するファイルでのみ変数を自動的に表示します。


4

これらの概念は直交しており、同じものと考えるべきではありません。

Constnessはアクセスの妥当性です。変数が読み取り専用(const)であるか書き込み読み取り(non-const)であるかのみを示します。

静的性は、存続期間(および技術的にはメモリローカリゼーション)プロパティです。変数がクラスのスコープ内でグローバルになるか(クラス内の場合)、変換ユニット(cppで定義されたグローバル変数とともに使用される場合)を示します。 。


-2

そうではなく、最も明白な例は、constメンバー変数(もちろんコンストラクターによって初期化される)がある場合、それはそのクラスのすべてのオブジェクトによって共有されるのではなく、それぞれに個別であるということです。

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litbは、上記の最良の答えを示します。


彼はいつもではないですか?(litb)
RastaJedi 2016年

-5

そうではありません。次のように書く:

const int i = 0;

i静的になりません(CまたはC ++のいずれかで)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.