extern const の使用法
質問1
1.cpp
extern const int i; //const int i = 1;
const int i = 1; //extern const int i;
int main(){return 0;}
2.cpp
extern const int i = 2;
コメントの順番通りならリンクが通るのに、これが通らないのはどう説明するのでしょうか?
質問2
C++で、グローバルシンボル定数を定義しなさい。
a.cpp で extern const double pi=3.14 を定義する。
b.ppでextern const double piを宣言する。
はコンパイルで実行できます。
a.cpp で const double pi=3.14 を定義する。
b.ppでextern const double piを宣言する。
コンパイルに失敗しました(a.cpp の pi 定数は extern キーワードで見つからず、スコープは a.cpp ファイルドメイン内のみです)。
この2つの問題については、明確にしなければならない概念がいくつかあります。
-
constオブジェクトはファイルローカル変数です。つまり、他のファイルはこのファイルのConst変数にリンクすることができません。
-
constの前にexternを付けると、このconstオブジェクトは他のファイルからリンクできることを意味します。
-
const変数をexternで初期化するのではなく、宣言を取得する場合、コンパイラはまずこのexternの前にあるオブジェクトの初期化宣言を探すことを選択します。これは、constのスコープが本質的にファイルスコープであるため、理解しやすいと思います。もし、自分自身のexternの前に見つからなかったら(コンパイラはコードをトップダウンでコンパイルするので、その後に何が来るかはわかりません)、そのオブジェクトの初期化にexternを使っている他の場所がないか、外を探します(他の場所でconst定数を初期化するには、それらすべてがexternを持っていなければなりません)。もしあれば、コンパイルは成功します。なければ、リンクエラーが報告されます。
課題1の分析。
上記の3つのポイントに目を通してください。あなたのコードを解釈してみましょう。1.cppで最初にextern const int iとすると、上記の3番目のポイントによると、まずiの初期化がないうちに自分自身を探しますが、明らかに何も見つかりません。そこで、ファイルの外に出て、リンクのプレースホルダーを探すと、2.cppにそのような定義が確かにあることがわかります。つまり、const i が見つかり、初期化されたのです。そしてその次の文はiの定義なので、コンパイルエラーではなくリンクエラーに違いありません:fatal error LNK1169: one or more multiply defined symbols found.
では、なぜその逆が起きないのでしょうか?最初の文はローカル変数iを定義して初期化しています。2番目の文はその変数をexternしています。extern変数がconstオブジェクトの場合、今度は自分のファイルの中を探し、見つかったらどこにもリンクしない。constはもともとファイルのドメインだからです。そうすると当然リンクエラーは発生しません。その結果をmain関数でiを出力して実行してみると、iの値が2ではなく1であることがわかります。
問題2解析。
定数変数は定義時に初期化する必要があるので、extern const double pi=3.14 in a.cpp; extern const double pi in b.pp; がコンパイル時に実行できるようになります。なぜなら,コンパイルシステムはa.cppでグローバル定数変数を見つけたとき,それがpiであることを知っており,それが切り替わったとき,const double pi=3.14 in a.cpp; extern const double pi in b.pp; を定義すると,コンパイルシステムはa.cppを問題なくコンパイルしますが,それがb.に来ると,コンパイルシステムはpiを初期化します. cppでは、外部定数が初期化されていないことがわかり(a.cppのconst定数はexternキーワードを持っていない)、定数は宣言された後に定義できないので、コンパイルシステムはその定義が見つからないと思い、エラーになります。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ハートビート・エフェクトのためのHTML+CSS
-
HTML ホテル フォームによるフィルタリング
-
HTML+cssのボックスモデル例(円、半円など)「border-radius」使いやすい
-
HTMLテーブルのテーブル分割とマージ(colspan, rowspan)
-
ランダム・ネームドロッパーを実装するためのhtmlサンプルコード
-
Html階層型ボックスシャドウ効果サンプルコード
-
QQの一時的なダイアログボックスをポップアップし、友人を追加せずにオンラインで話す効果を達成する方法
-
sublime / vscodeショートカットHTMLコード生成の実装
-
HTMLページを縮小した後にスクロールバーを表示するサンプルコード
-
html のリストボックス、テキストフィールド、ファイルフィールドのコード例