Pregunta

Tengo el siguiente programa:

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

Estoy compilando este programa usando GCC 4.2.2 en Linux que se ejecuta en una máquina Intel de 64 bits con varias CPU:

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

Cuando compilo el programa en modo de 64 bits, compila y enlaza bien:

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

Cuando lo compilo en modo de 32 bits, aparece el siguiente error:

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

Aunque en realidad nunca voy a ejecutar un procesador de 32 bits, necesito un ejecutable de 32 bits para poder vincularme con algunas bibliotecas de 32 bits.

Mis 2 preguntas son:

  1. ¿Por qué recibo un error de enlace cuando compilo en modo de 32 bits?

  2. ¿Hay alguna forma de hacer que el programa se compile y se enlace, sin dejar de poder vincularse con una biblioteca de 32 bits?

¿Fue útil?

Solución

De la página GCC en Atomic Construidos :

  

No todas las operaciones son compatibles con   Todos los procesadores de destino. Si un particular   la operación no se puede implementar en el   procesador de destino, una advertencia será   generado y una llamada externa   Se generará la función. los   la función externa llevará lo mismo   nombre como el incorporado, con un   sufijo adicional `_n 'donde n es el   tamaño del tipo de datos.

A juzgar por la salida del compilador, que se refiere a __sync_add_and_fetch_4 , esto es lo que está sucediendo. Por alguna razón, GCC no está generando la función externa correctamente.

Esta es probablemente la razón por la que solo obtiene un error en el modo de 32 bits: al compilar para el modo de 64 bits, se compila para su procesador más de cerca. Al compilar para 32 bits, puede estar usando un arco genérico (i386, por ejemplo) que no admite de forma nativa esas características. Intente especificar una arquitectura específica para su familia de chips (Xeon, Core 2, etc.) a través de -mcpu y vea si eso funciona.

Si no, tendrá que descubrir por qué GCC no incluye la función apropiada que debería estar generando.

Otros consejos

La respuesta de Dan Udey fue cercana, lo suficientemente cerca como para permitirme encontrar la solución real.

De acuerdo con la página man " -mcpu " es un sinónimo obsoleto de " -mtune " y solo significa "optimizar para una CPU en particular (pero aún se ejecuta en CPU más antiguas, aunque menos óptimas)". Intenté esto y no resolvió el problema.

Sin embargo, " -march = " significa "generar código para una CPU en particular (y no ejecutar en CPU más antiguas)". Cuando probé esto, resolvió el problema: al especificar una CPU de i486 o mejor se eliminó el error de enlace.

~/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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top