1

メインプログラムがあります:

#include <stdio.h>
extern int a;
int main (int argc, char ** argv) {
    int i;
    printf ("Hello %p, %p\n", & i, & a);
    return 0;
}

foo.c変数 の私の定義を含む別のファイルa:

int a;

私がこのように構築した場合:

clang -c main.c foo.c
clang main.o foo.o
./a.out

すべては順調です。しかし、私が次のことをすると:

ar rvs bar.a foo.o

わからないという警告が出ます

r - foo.o
warning: /<elided>/ranlib: 
warning for library: bar.a the table of contents is empty 
(no object file members in the library define global symbols)

ライブラリをチェックして、シンボルがそこにあることを確認します

nm bar.a

bar.a(foo.o):
0000000000000004 C _a

そして、私はします

clang main.o bar.a

次のエラーが表示されます

Undefined symbols for architecture x86_64:
  "_a", referenced from:
      _main in main-5121f1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

私は何を取りこぼしたか?

4

1 に答える 1

2

int a;問題は、インfoo.cが暫定的な定義であることだと思います。Cからの出力では (共通)とマークされていますnm。明示的に初期化した場合(0一貫性のために、テスト目的で確認するためにゼロ以外の値に)、問題はないと思います。

TU の最後に、暫定的な定義を定義に変換する必要があるため、完全には確信が持てません。

ISO/IEC 9899:2011 §6.9.2 外部オブジェクト定義

¶2 初期化子がなく、ストレージクラス指定子がない、またはストレージクラス指定子が static のファイルスコープを持つオブジェクトの識別子の宣言は、暫定的な定義を構成します。翻訳単位に識別子の暫定的な定義が 1 つ以上含まれており、翻訳単位にその識別子の外部定義が含まれていない場合、動作は、翻訳単位にその識別子のファイル スコープ宣言が含まれているかのように、複合型は次のようになります。 0 に等しい初期化子を使用して、翻訳単位の末尾を指定します。

C のソース ファイル間で変数を共有するにはどうすればよいですか?も参照してください。

于 2014-07-31T04:03:18.560 に答える