15

静的変数にはファイルスコープがあります。次の2つのファイルがあるとします。

  • file1.h
  • file1.cpp
  • file2.h
  • file2.cpp

static int Var1両方のヘッダーファイルで静的変数sayを宣言しました。file1.hとの両方file2.hがファイルに含まれていmain.cppます。

静的変数にはファイルスコープがあり、互いに競合しないため、これを行いました。しかし、コンパイル後、競合が発生していることがわかりました。

これで、静的変数は変数のように動作しexternます。一方、両方の.cppファイルで静的変数を宣言すると、正常にコンパイルされます。

私はこの振る舞いを理解することができません。

このシナリオでスコープとリンケージがどのように機能しているかを説明できる団体はありますか。

4

3 に答える 3

21

静的変数はコンパイル単位に対してローカルです。コンパイルユニットは、基本的に、各ディレクティブの代わりにファイル.cppの内容が.h挿入されたファイルです。#include

現在、コンパイルユニットでは、同じ名前の2つのグローバル変数を持つことはできません。これがあなたのケースで起こっていることです:main.cppincludesfile1.hfile.h、そして2つのヘッダーのそれぞれがそれ自身のを定義しVar1ます。

論理的にこれらが2つの異なる変数である場合は、それらに異なる名前を付けます(または異なる名前空間に配置します)。

これらが同じ変数である場合は、別のヘッダーファイルに移動し、との両方からvar1.hインクルードします。ただし、の#includeガードを忘れないでください。var1.hfile1.hfile2.hvar1.h

于 2011-02-18T11:11:59.257 に答える
13

静的変数には変換単位のスコープ(通常は.cまたは.cppファイル)がありますが、#includeディレクティブはファイルのテキストを逐語的にコピーするだけで、別の変換単位を作成しません。前処理後、これは:

#include "file1.h"
#include "file2.h"

これに変わります:

/* file1.h contents */
static int Var1;

/* file2.h contents */
static int Var1;

ご存知のように、これは無効です。

于 2011-02-18T11:17:37.157 に答える
3

静的変数static int Var1が両方のヘッダーでグローバルスコープにあり、両方のヘッダーがに含まれていると仮定しますmain.cpp。ここで、最初にプリプロセッサが含まれているファイルの内容をにコピーしますmain.cpp。で、同じスコープで2回宣言さmain.cppれるVar1ため、複数の宣言エラーが発生します。(つまり、一方はプリプロセッサからコピーされfile1.h、もう一方file2.hはプリプロセッサによってコピーされます)

各ソースファイルは個別にコンパイルされます。これで、ソースファイルで個別に宣言すると、各ソースファイルは、同じ名前を持つ他のソースファイルに存在する他の静的変数の存在を認識しなくなります。したがって、コンパイラはエラーを報告しません。ソースファイル間で変数を共有したい場合は、externとしてマークすることができます。

于 2011-02-18T11:17:03.013 に答える