3

この(リンク)の質問で私の問題を説明するために、リンカーがどのように機能するか、およびこのプロセスに関連するすべてについて読んでいます(短いですが、参照については申し訳ありませんが、関連性があります)。

質問: ヘッダーに(externを使用して)変数宣言があり、この変数を複数のソースファイル(#各コースのヘッダーファイルを含む)で使用したい場合は、これの定義を提供する必要がありますどこかで変数。問題は、たとえば一部のソースファイルのmain関数で定義を指定した場合でも、他のファイルはこの定義を「認識」しないことです(これによりリンクエラーが発生します)。このextern変数をグローバルスコープの1つで定義すると、正常に機能し、誰もがそれを見ることができます。

なんで?他のファイルはどのようにして別のファイルのグローバルスコープにアクセスできますか?そして、グローバルスコープ変数は危険ではありませんか?変数定義を他のどのスコープに配置すると、このようなリンクエラーを解決できますか?誰かがヘッダーでそのような外部変数宣言をどのような目的で使用しますか?

編集:正確な例の状況は、私が最初に投稿したリンクにあります

4

2 に答える 2

5

いくつかの説明:

あなたが「ファイル」と呼んでいるものは、より適切には翻訳単位と呼ばれています。関係するファイルの数は関係ありません。実際、同じファイルを再コンパイルすることができます(たとえば、異なる#definesを使用するなど)。

その用語で武装して、あなたの質問を言い換えることができます:「翻訳ユニットはどのようにして別の翻訳ユニットのグローバルスコープにアクセスできますか?」

リンケージに関するウィキペディアの記事からの引用:

名前に外部リンケージがある場合、その名前が示すエンティティは、同じ名前の個別の宣言を使用して別の翻訳単位から参照されたり、個別の宣言を使用して同じ翻訳単位内の他のスコープから参照されたりする場合があります。

言い換えると、その名前を外部リンケージとして確認することにより、それはグローバルスコープ内にあり、翻訳単位ではなく、プログラムに対してグローバルになります。

残りの質問:

  1. グローバルスコープ変数は危険ではありませんか?

    セキュリティ上の欠陥などがある特定の標準ライブラリ関数のように、「危険」という言葉を使用してそれらを説明することは決してありません。しかし、コードの設計が非常に不十分になる可能性が非常に高く、特にグローバル変数の場合はそうです。 、マルチスレッドコードでの多くの頭痛の種。良いルール:そうしない正当な理由がない限り、それらを避けてください。

  2. リンケージエラーを回避する方法(他のスコープで)

    ここには他の魔法の宣言はありません。翻訳ユニットの外部に表示されるか(外部)、表示されないか(静的)です。おそらくあなたが求めているのは、「他のモジュールに変数にアクセスさせる正しい方法は何ですか?」です。そしてその答えは次のとおりです。アクセサ関数(またはさらに良いことに、メソッドを使用してそのデータを管理するクラス)を記述します。

  3. 誰がこのようなものをどのような目的で使用しますか?

    常に熱く議論されているトピック。多くの人が完全に避けることを勧めていますが、十分なサイズのプロジェクトで外部を見つけないようにするのは難しいでしょう。最良の理由は通常、純粋主義者が無視する種類のものに帰着します。レガシーシステムとの互換性、パフォーマンス、デバッガーやその他の内省ツールへの簡単なアクセス…またはもちろん、それが簡単で、理解され、機能したからです。

于 2012-12-30T08:08:31.827 に答える
3

変数を配置するときin the main functionは、その関数に表示されるローカル変数を定義します。

1つのソースファイルのファイルスコープで変数を定義する必要があります。

于 2012-12-30T08:04:02.523 に答える