Problemas del enlazador de C ++

Tengo esto:

a.cpp

int localfunction () { return 1; } int local_symbol = localfunction(); 

b.cpp

 void thirdfunction () {}; 

main.cpp

 void main () { thirdfunction (); } 

Cuando compilo esto en un ejecutable principal, todo funciona (incluso con optimizaciones), y la función local se ejecuta al inicio, incluso si no lo llamo directamente.

Ahora, en Visual C ++ y GCC, puse a.cpp y b.cpp en una biblioteca estática (.lib). La función local ya no se ejecuta / define.

Por lo que entiendo, el símbolo se detecta como “no utilizado” y se elimina. Pero suena raro porque:

  • ¿Por qué no se elimina cuando no uso el archivo .lib?
  • Dado que la biblioteca está vinculada, ¿por qué el enlazador elimina el código de inicialización?

Lo que estoy tratando de hacer es tener un conjunto de funciones de inicio en cada archivo .lib que utilizo para registrar automáticamente algunos datos. El ejecutable principal no debe saber en qué archivos están vinculados ni hacer referencia explícita a “función local” (/ INCLUDE funciona pero no es óptimo)

Por cierto: el uso de varias opciones de VC ++ (OPT: NOREF, etc.) no resuelve el problema.

¡Gracias! QbProg

Una biblioteca estática es, básicamente, una biblioteca, o archivo, de archivos de objetos comstackdos a partir de los archivos fuente constituyentes de esa biblioteca.

Cuando el enlazador usa una biblioteca estática para resolver dependencias mientras construye una aplicación, sigue un proceso de búsqueda de archivos de objetos en la biblioteca que lo ayudan a resolver cualquier símbolo indefinido en el progtwig. No incluye automáticamente todos los archivos de objetos en una biblioteca.

En su instancia, el archivo objeto generado desde main.cpp refiere a third_function() . Esta dependencia se puede resolver vinculando el archivo de objeto generado desde b.cpp . Este archivo de objeto no introduce más símbolos indefinidos, por lo que el vinculador puede (y lo hace) detenerse aquí.

Ah, y para main portabilidad main debe devolver int .

Cuando utilizo gcc y necesito una función de inicio que se ejecute “automáticamente” antes de que se ejecute main (), solo usaría __attribute__((constructor)) .

Tal vez haya una forma similar (pragma?) Para definir una función en VC ++, entonces podrías hacer algo de magia de preprocesador para tener una forma común de declarar esas funciones de inicio.

Su enlazador tomará medidas para reducir el tamaño del ejecutable. Determinará que su exe no usa la función ‘said’ y no la incluye en su código final generado. Aunque también depende de qué optimización esté utilizando en su proyecto.

En cambio, si desea hacer esto dinámicamente, la mejor alternativa es usar LoadLibrary y crear una DLL que todos sus progtwigs puedan cargar y cargar dinámicamente la función y registrar lo que necesita.

Hay que recordar los viejos tiempos en que el tamaño era una prima.

Tienes una biblioteca de matemáticas masiva con 10,000 funciones diferentes. Ahora tu aplicación usa sin () y tu vinculas contra libm.a (o -lm).

Definitivamente, no desea copiar su aplicación con 9,999 funciones que no usa. Así que cuando se usan librerías estáticas, solo se extrae de la biblioteca exactamente lo que se usa (nada más).

Por otro lado, las bibliotecas compartidas están diseñadas para que todo se almacene en la memoria. Además (aunque no está definido en ningún estándar) la mayoría de los cargadores dynamics también ejecutarán cualquier código de inicialización estático a medida que se cargan. (Tenga en cuenta que si los vincula contra ellos, generalmente se cargan al inicio de la aplicación).