在32位模式下编译gcc原子操作时发生链接错误

在32位模式下编译gcc原子操作时发生链接错误,gcc,linker,atomic,Gcc,Linker,Atomic,我有以下计划: ~/test> cat test.cc int main() { int i = 3; int j = __sync_add_and_fetch(&i, 1); return 0; } 我在多cpu 64位Intel机器上运行的Linux上使用GCC 4.2.2编译此程序: ~/test> uname --all Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64

我有以下计划:

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}
我在多cpu 64位Intel机器上运行的Linux上使用GCC 4.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位库

我的两个问题是:

  • 为什么在32位模式下编译时会出现链接错误

  • 是否有某种方法可以让程序编译和链接,同时仍然能够链接到32位库

  • 从:

    并非所有操作都受支持 所有目标处理器。如果某个特定的 无法在上执行操作 目标处理器,将显示警告 生成并调用外部 函数将被生成。这个 外部功能将携带相同的信息 将名称命名为内置项,并带有 附加后缀“\u n”,其中n是 数据类型的大小

    从您的编译器输出判断,它引用了
    \uuuuuu sync\uadd\u和\ufetch\u4
    ,这就是发生的情况。由于某些原因,GCC没有正确地生成外部函数

    这可能就是为什么您只会在32位模式下收到一个错误-当编译为64位模式时,它会更紧密地为您的处理器编译。当编译32位时,它很可能使用一个通用的arch(例如i386),它本机不支持这些特性。尝试通过-mcpu为您的芯片系列(Xeon、Core 2等)指定一种特定的体系结构,看看是否可行


    如果没有,你就必须弄清楚为什么GCC没有包含它应该生成的适当函数。

    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
    

    这个答案非常接近,事实上非常接近,让我找到了真正的解决方案,我已经分别发布了。在gcc-4.1.2上,我们可以使用“-march=i486”编译器标记将其链接起来,并可以在gcc 4.7.3上用_u原子fetch add确认相同的问题。i386给出了uuu原子u fetch u add 4未定义的引用。i486、i586、i686不需要。线程库使用了uuu原子u fetch u add.Oh哇…-mtune=i386对我来说很有用!同样的测试程序。尝试了
    \uuuuuu原子\u同步\u和
    \uuuu原子\u取数
    。也许mtune在gcc 4.7.3和4.2.2中有所改进。