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

StackOverflow https://stackoverflow.com/questions/130740

  •  02-07-2019
  •  | 
  •  

Вопрос

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

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

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

  2. Есть ли какой-нибудь способ заставить программу скомпилироваться и связать, сохраняя при этом возможность соединения с 32-разрядной библиотекой?

Это было полезно?

Решение

Из самого Страница GCC о встроенных атомах:

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

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

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

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

Другие советы

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

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

Однако "-march=" означает "генерировать код для определенного процессора (и не запускать на старых процессорах)".Когда я попробовал это, это решило проблему:указание процессора 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top