Подтвердить что ты не робот

Ошибка связи при компиляции атомной операции gcc в 32-битном режиме

У меня есть следующая программа:

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

Я компилирую эту программу, используя GCC 4.2.2 для Linux, работающую на 64-битной машине Intel с несколькими процессорами:

~/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 вопроса:

  • Почему я получаю ошибку связи при компиляции в 32-битном режиме?

  • Есть ли способ, чтобы программа могла компилировать и связывать, в то же время имея возможность связываться с 32-битной библиотекой?

4b9b3361

Ответ 1

На странице GCC на Atomic Builtins:

Не все операции поддерживаются все целевые процессоры. Если конкретный не могут быть реализованы на целевого процессора, предупреждение будет сгенерированный и вызов внешнего будет генерироваться функция. внешняя функция будет нести то же самое имя как встроенный, с дополнительный суффикс `_n ', где n - размер типа данных.

Судя по вашему компилятору, который относится к __sync_add_and_fetch_4, это то, что происходит. По какой-то причине GCC неправильно генерирует внешнюю функцию.

Вероятно, это связано с тем, что вы получаете ошибку только в 32-битном режиме - при компиляции для 64-битного режима она более точно компилируется для вашего процессора. При компиляции для 32-разрядной версии вполне может быть использована общая арка (например, i386), которая не поддерживает эти функции. Попробуйте указать конкретную архитектуру для семейства чипов (Xeon, Core 2 и т.д.) Через -mcpu и посмотреть, работает ли это.

Если нет, вам нужно выяснить, почему GCC не включает соответствующую функцию, которую он должен генерировать.

Ответ 2

Ответ от Дэна Удей был близок, достаточно близко, чтобы позволить мне найти реальное решение.

В соответствии с man-страницей "-mcpu" является устаревшим синонимом "-mtune" и просто означает "оптимизировать для определенного процессора (но все еще работать на старых процессорах, хотя и менее оптимально)". Я попробовал это, и это не решило проблему.

Однако "-march =" означает "сгенерировать код для конкретного процессора (и не запускаться на старых процессорах)". Когда я попробовал это, он решил проблему: указав CPU i486 или лучше избавившись от ошибки связи.

~/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