17

私は次のプログラムを持っています:

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}

マルチCPU64ビットIntelマシンで実行されているLinuxでGCC4.2.2を使用してこのプログラムをコンパイルしています。

~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

プログラムを64ビットモードでコンパイルすると、正常にコンパイルおよびリンクされます。

~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>

32ビットモードでコンパイルすると、次のエラーが発生します。

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>

実際に32ビットプロセッサで実行することはありませんが、いくつかの32ビットライブラリとリンクできるように、32ビットの実行可能ファイルが必要です。

私の2つの質問は次のとおりです。

  1. 32ビットモードでコンパイルするとリンクエラーが発生するのはなぜですか?

  2. 32ビットライブラリとリンクしながら、プログラムをコンパイルしてリンクする方法はありますか?

4

2 に答える 2

24

Dan Udey からの回答は非常に近いものでした。実際、私が本当の解決策を見つけるのに十分なほど近いものでした。

マニュアルページによると、「-mcpu」は「-mtune」の非推奨の同義語であり、単に「特定の CPU 向けに最適化する (ただし、最適性は低くなりますが、古い CPU でも実行できます)」という意味です。これを試しましたが、問題は解決しませんでした。

ただし、「-march=」は「特定の CPU 用のコードを生成する (古い CPU では実行しない)」ことを意味します。これを試してみると、問題は解決しました。i486 以上の CPU を指定すると、リンク エラーが解消されました。

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc
于 2008-09-25T00:33:39.450 に答える
15

Atomic BuiltinsのGCCページから:

すべての操作がすべてのターゲットプロセッサでサポートされているわけではありません。ターゲットプロセッサで特定の操作を実装できない場合は、警告が生成され、外部関数の呼び出しが生成されます。外部関数には、組み込み関数と同じ名前が付けられ、接尾辞「_n」が追加されます。ここで、nはデータ型のサイズです。

を参照するコンパイラ出力から判断すると__sync_add_and_fetch_4、これが起こっていることです。何らかの理由で、GCCが外部関数を正しく生成していません。

これが、32ビットモードでのみエラーが発生する理由である可能性があります。64ビットモードでコンパイルすると、プロセッサにより厳密にコンパイルされます。32ビット用にコンパイルする場合、これらの機能をネイティブにサポートしていない汎用arch(i386など)を使用している可能性があります。-mcpuを使用して、チップファミリ(Xeon、Core 2など)の特定のアーキテクチャを指定してみて、それが機能するかどうかを確認してください。

そうでない場合は、GCCが生成する必要のある適切な関数が含まれていない理由を理解する必要があります。

于 2008-09-25T00:18:46.130 に答える