2011-08-25 11 views
8

2つの異なる.cファイルに2つの同一のグローバル変数があり、externとして宣言されていません。だから、各.cファイルは自分自身の変数を見たはずですか?同じ名前とタイプの2つの変数、2つの異なる.cファイル、gccでコンパイル

しかし、1つのファイルが他のファイル変数を読み込んでいるかのように(実際にそれらをリンクした後のように)、私は本当に奇妙な動作をしています。両方の変数定義に 'static'修飾子を追加すると、この問題が修正されたようです。

私が実際に思っているのは、静的な修飾子がないと正確に何が起こったのでしょうか?

+1

も参照してくださいhttp://stackoverflow.com/questions/1490693/externリンケージのトリッキーな側面のためのc99-and-linkingの仮定義。 –

+0

@Pascalあなたの答えは実際には最も完成した、あまりにも悪い私は受け入れられたものとしてそれをフラグすることはできません。私はあなたが 'nm 'で行ったことに似た何かをやって自分自身を考えました。この状況について私の頭に浮かぶのは、それが標準の大きな欠陥であるということだけです。ここでもhttp://www.jetcafe.org/jim/c-style.html#need_externについて話しています。コンパイラが 'extern'修飾子を前提としていればいいと思っていたのですか?そのような愚かな前提を作るのは、地獄ではないと確信しています。 – johndoevodka

答えて

18

それぞれの.cファイルには独自の変数があるはずですか?

間違っています。 Cでは、宣言からstaticを省略すると、暗黙のexternリンケージが意味されます。一言で言えばCから

コンパイラ扱い関数宣言ストレージクラス 指定せず、それらは指定子EXTERNを含んでいるかのように。同様に、すべての機能の外で宣言し、 のストレージクラス指定子を持たない任意の オブジェクト識別子はであり、external linkageです。

+0

ありがとう、私はそれを知らなかった。なぜコンパイラはエラーや警告を出しませんでしたか? – johndoevodka

+2

参考のため、Visual Studio 2008とGCC 4.3.5の両方がこのルールに従います。また、VCで.cpp拡張子に変更するか、linuxでg ++を呼び出すことで、C++コンパイラでコードを再コンパイルすると、 "多重定義"リンクエラーが発生します。 – Zac

0

私が知っている限り、あなたは静的でもexternも指定していないときは、コンパイラが選択する必要があります。この場合はgccがexternになりますので、あなたの場合は静的に指定する必要があります。

私は

1

出力ファイルを個別にリンカによってそれらを一緒にリンクする次に、ファイルのオブジェクトファイルを作ることによって生成された:-)数年前、同じ問題を抱えていました。今では2つの異なるファイルに同じ変数がある場合、個々のファイルはエラーなしでコンパイルされますが、リンク時にはリンカは変数の2つの定義を取得し、エラーを生成します。しかし両方の静的スコープの場合は、ファイルのための変数の制限は、すべてのものがうまく動作します。 私はこれが役に立つと思います。

2

常にグローバル変数を初期化すると、コンパイラは自動的にexternとしてそのリンケージを考慮しません。コンパイラはコンパイル中にエラーをスローします。これは、我々のコードは、他の誰かが宣言(当社ロジックの観点で)いくつかのランダムな値を持つ変数を使用する可能性があるため、大きなコードベースにランダムな問題を回避するのに役立ちます

関連する問題