Name mangling, RTTI y compatibilidad entre compiladores

60 views
Skip to first unread message

Joaquin Duo

unread,
Mar 29, 2012, 11:27:02 PM3/29/12
to cp...@googlegroups.com
Hola Lista!
Gracias por sus respuestas!

Diseñando el sistema de plugins me han surgido ciertas dudas.
Mi idea en el diseño es que los plugins se puedan compilar con diferentes compiladores, y que la compatibilidad con el sistema tenga larga duración.
En otras palabras, que no haga falta compilar nuevamente el plugin si cambia el compilador.
Aunque no es un requisito fundamental me interesa saber cómo se comportan las compatibilidades entre compiladores.

1- Respecto al name mangling:
Tengo entendido que el name mangling cambia de un compilador a otro. Pero también de una versión a otra, no?
No existe ahora un estándar que diga cómo debería ser el name mangling?
Sí o sí tengo que compilar los plugins con la misma versión (o versiones cercanas) del compilador?
Cuáles son los límites?

Suponiendo que evito el problema usando una función de interface 'extern "C"'.
Qué compatibilidad hay a nivel lógico/de compilación entre compiladores?

Suponiendo los siguientes pasos:
1- ambos compiladores leen la misma definición de una clase.
2- el núcleo de la aplicación es compilado con un compilador A, que usa esa clase
3- el plugin es compilado con el compilador B, que usa la clase.
4- el núcleo carga la librería y recibe, luego de llamar una función de la librería, un puntero a la clase creada por B.
Pueden haber incompatibilidades?

2- Respecto a RTTI:
Tengo las mismas dudas que para las compatibilidades entre clases.
Qué sucede con el RTTI en diferentes compiladores? Hay incompatibilidades?

Espero que la pregunta sea interesante.
Gracias desde ya!

Daniel Gutson

unread,
Mar 29, 2012, 11:45:30 PM3/29/12
to cp...@googlegroups.com
Joaquín,

  te sugerí que miraras unplugged.googlecode.com, lo viste? Viste los ejemplos?

Vamos por partes porque hay mucho para responder.

Vos, primero, sabés que el problema no es tanto el compilador, sino el DYNAMIC LOADER del sistema operativo?

El binding entre la aplicación y un shared object ocurre dinámicamente por la acción del DYNAMIC LOADER, que es un componente del sistema operativo.

El compilador ("casi" sin linker, puedo explicar en más detalle), es amigo del sistema operativo target, ya que respeta lo que se llama ABI (Application Binary Interface), un documento que escriben de la manito el fabricante del sistema operativo y el fabricante del microprocesador.

NO HAY NAME MANGLING al menos en linux (no sé en windows), es todo C-calling conventions.

Y por último, si el plugin genera una instancia de una clase escrita en un .h, que la aplicación usará, ni siquiera hace falta que cambies de compilador para tener kilombo: basta con que hayas compilado con distintas opciones de empaquetamiento para que se rompa todo.

Ahora bien, fijáte el link y después contáme para qué querés hacer esto.
Ni C ni C++ tienen interés desde diseño en ser binary-compatible codes, para eso está Java y .net.

2012/3/30 Joaquin Duo <joa...@gmail.com>

--
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"



--
Who’s got the sweetest disposition?
One guess, that’s who?
Who’d never, ever start an argument?
Who never shows a bit of temperament?
Who's never wrong but always right?
Who'd never dream of starting a fight?
Who get stuck with all the bad luck?

Daniel Gutson

unread,
Mar 29, 2012, 11:52:04 PM3/29/12
to cp...@googlegroups.com
Aclaración extra:

  la razón de la existencia del name mangling, es histórica:

los fabricantes de los linkers(*) son unos vagos que no quieren que les rompan las bolas con "detalles" de lenguajes (el linker linkea archivos objeto generados con cualquier compilador de cualquier lenguaje).
Apareció el C++ con su overloading y que una función ya no es más unívocamente identificable por su nombre, y los del linker por supuesto dijeron "minga! arregláte!"...
Ese fue el comienzo de la larga lista de argucias ridículas que hubo que hacer porque los del linker no quieren laburar de más, y que el lugar natural (y mucho más simple) de implementar sería el linker.



(*) queda poco político que diga "los creadores de GNU Ld"

2012/3/30 Daniel Gutson <daniel...@gmail.com>

Daniel Gutson

unread,
Mar 29, 2012, 11:55:36 PM3/29/12
to cp...@googlegroups.com
Aclaro algo más y me voy a dormir con fiebre:
   todo esto que mencionás tendrías igual de problema aún sin dynamic loading, lo tendrías tanto en static como dynamic linking también.
Es decir, es un problema de linking,
 no importa que ocurra en momento de linking de la aplicación, en momento de start-up de la aplicación, u on-demand en runtime.

2012/3/30 Daniel Gutson <daniel...@gmail.com>

Joaquin Duo

unread,
Mar 30, 2012, 2:35:45 PM3/30/12
to cp...@googlegroups.com
On Fri, Mar 30, 2012 at 12:45 AM, Daniel Gutson <daniel...@gmail.com> wrote:
Joaquín,

  te sugerí que miraras unplugged.googlecode.com, lo viste? Viste los ejemplos?
Sí, lo ví. Debería probarlo con más profundidad.
Ya tengo una versión funcional del sistema de plugins.
Sin embargo está pensado con interfaces en C, para que también se puedan escribir plugins en C.
La idea es luego hacer una clase en C++ Wrapper  de las funciones de comunicación con el núcleo de la aplicación.
Así los plugins en C++ tendrán una interface más cómoda.
Cuando aborde esta etapa seguramente los consulte.
 
Vamos por partes porque hay mucho para responder.

Vos, primero, sabés que el problema no es tanto el compilador, sino el DYNAMIC LOADER del sistema operativo?
Sí. :-)

El binding entre la aplicación y un shared object ocurre dinámicamente por la acción del DYNAMIC LOADER, que es un componente del sistema operativo.

El compilador ("casi" sin linker, puedo explicar en más detalle), es amigo del sistema operativo target, ya que respeta lo que se llama ABI (Application Binary Interface), un documento que escriben de la manito el fabricante del sistema operativo y el fabricante del microprocesador.

NO HAY NAME MANGLING al menos en linux (no sé en windows), es todo C-calling conventions.
No comprendo a qué te referís. En el siguiente email mencionás que
"  la razón de la existencia del name mangling, es histórica:"
Sé que la tabla de símbolos solo acepta cierto tipo de formato de nombre. Como explicas en el siguiente correo.

Y por último, si el plugin genera una instancia de una clase escrita en un .h, que la aplicación usará, ni siquiera hace falta que cambies de compilador para tener kilombo: basta con que hayas compilado con distintas opciones de empaquetamiento para que se rompa todo.

Ahora bien, fijáte el link y después contáme para qué querés hacer esto.
Ni C ni C++ tienen interés desde diseño en ser binary-compatible codes, para eso está Java y .net.
Saquemos del contexto a los plugins. Ahora mi interés es meramente teórico.
Quisiera saber cuándo se rompen las compatibilidades y cuándo no.

Dentro de un mismo compilador:
Por ejemplo. Si yo tengo las librerías QT y las compilo con gcc-A.B, donde A y B son numeros
Dandome como resultado un .a o .so (no debería haber diferencia como decís)
Si compilo mi aplicación linkeando contra la librería: (suponiendo que utilizo las mismas opciones de empaquetamiento)
1- con gcc-A.B (tiene que andar)
2- con gcc-A.(B+1) (andaría?)
3- con gcc-(A+1).(B+x) (ya es seguro que se rompe?)

En diferentes compiladores:
Por otro lado mencionás que ni siquiera C es binary-compatible.
Esto se traduce a que no existen en el mundo sistemas que utilicen librerías compiladas con diferentes compiladores?
O hay ciertos límites dentro de los cuales se puede llamar otras funciones y pasarles parámetros? (y que parámetros y resultados sean tipos estándares o que sigan alguna regla)

Gracias por las respuestas!
Espero que te mejores de la angina.
 

Daniel Gutson

unread,
Mar 30, 2012, 3:02:34 PM3/30/12
to cp...@googlegroups.com


2012/3/30 Joaquin Duo <joa...@gmail.com>

On Fri, Mar 30, 2012 at 12:45 AM, Daniel Gutson <daniel...@gmail.com> wrote:
Joaquín,

  te sugerí que miraras unplugged.googlecode.com, lo viste? Viste los ejemplos?
Sí, lo ví. Debería probarlo con más profundidad.
Ya tengo una versión funcional del sistema de plugins.
Sin embargo está pensado con interfaces en C, para que también se puedan escribir plugins en C.

por qué es algo distinto a lo que propone dlfcn.h ?
 
La idea es luego hacer una clase en C++ Wrapper  de las funciones de comunicación con el núcleo de la aplicación.
Así los plugins en C++ tendrán una interface más cómoda.

(insisto en que deberías ver plugin.h :) )
 
Cuando aborde esta etapa seguramente los consulte.
 
Vamos por partes porque hay mucho para responder.

Vos, primero, sabés que el problema no es tanto el compilador, sino el DYNAMIC LOADER del sistema operativo?
Sí. :-)

El binding entre la aplicación y un shared object ocurre dinámicamente por la acción del DYNAMIC LOADER, que es un componente del sistema operativo.

El compilador ("casi" sin linker, puedo explicar en más detalle), es amigo del sistema operativo target, ya que respeta lo que se llama ABI (Application Binary Interface), un documento que escriben de la manito el fabricante del sistema operativo y el fabricante del microprocesador.

NO HAY NAME MANGLING al menos en linux (no sé en windows), es todo C-calling conventions.
No comprendo a qué te referís.

Sí fui poco claro: que no hay name mangling en el soporte a dynamic loading, porque es todo C-calling types. Y porque es una librería de C.
 
En el siguiente email mencionás que
"  la razón de la existencia del name mangling, es histórica:"
Sé que la tabla de símbolos solo acepta cierto tipo de formato de nombre.

tabla de símbolos? de quién? del compilador? No, en ese caso la tabla de símbolos del compilador no tiene nada que ver. La tabla de símbolos del compilador vive temporalmente mientras compila, y se usa para hacer lookup de símbolos justamente. El name mangling aparece mucho después, al momento de escribir esos símbolos en el archivo objeto para que el linker no se ofenda. Te aconsejo jugar con c++filt.
 
Como explicas en el siguiente correo.

Y por último, si el plugin genera una instancia de una clase escrita en un .h, que la aplicación usará, ni siquiera hace falta que cambies de compilador para tener kilombo: basta con que hayas compilado con distintas opciones de empaquetamiento para que se rompa todo.

Ahora bien, fijáte el link y después contáme para qué querés hacer esto.
Ni C ni C++ tienen interés desde diseño en ser binary-compatible codes, para eso está Java y .net.
Saquemos del contexto a los plugins. Ahora mi interés es meramente teórico.
Quisiera saber cuándo se rompen las compatibilidades y cuándo no.

Dentro de un mismo compilador:

xfa distingamos compilador de linker, porque en esta discusión es muy relevante. Yo te puedo romper compatibilidad binaria sólo entre compiladores, sin meter al linker en el medio. Te muestro debajo cómo.
Y decir "gcc" no es suficiente, porque gcc es el "compiler driver", es decir, el programa titiritero que invoca a los distintos componentes del toolchain: preprocesador, compilador, ensamblador, y eventualmente linker.
 
Por ejemplo. Si yo tengo las librerías QT y las compilo con gcc-A.B, donde A y B son numeros
Dandome como resultado un .a o .so (no debería haber diferencia como decís)
Si compilo mi aplicación linkeando contra la librería: (suponiendo que utilizo las mismas opciones de empaquetamiento)
1- con gcc-A.B (tiene que andar)

No necesariamente, por estas dos razones:
  1) uses distintos parámetros de compilación (ahora muestro)
  2) linkees contra distintas versiones de librerías. Conocés ldd? buscálo y probálo.

 
2- con gcc-A.(B+1) (andaría?)
3- con gcc-(A+1).(B+x) (ya es seguro que se rompe?)

Como te comento arriba, aún dentro de una misma versión no está garantizada la compatibilidad.

Se me ocurren al menos tres factores fundamentales que pueden romper compatibilidad binaria usando el mismo compilador.

  a) empaquetamiento de datos
  b) cant bits
  c) multilibs


a) empaquetamiento

considerá

struct Pepe
{
   char a;
   int b;
};

en qué posición empieza b? (es decir, cuánto vale offsetof(Pepe, b) ?)

b) cant de bits: compilaste el coso para 32bits y el plugin para 64 o viceversa. Hay otras plataformas (ej ARM) en que hay tanta combinación de flags que controlan la generación del binario, no sólo cant. de bits.. por ejemplo sin ir más lejos, endianness. Podés tener el core compilado como big endian y el plugin como little endian. Preguntále a la nasa cómo le fue por algo así :)

c) multilibs (esto es bastante gcc)
El concepto de "multilib" es que la instalación de gcc viene equipada con las librerías buildeadas en varios sabores, de manera que según el target y las opciones que especifiques a gcc (no sólo cant. de bits, sino tipo de FPU, etc., cosas relevantes en otras plataformas), elegirá aquella que más se parece o mejor se ajusta. Por ejemplo, en x86, las dos que están como mínimo son la multilib de 32 y la de 64 bits.
Entonces, el compiler driver elegirá la multilib adecuada dependiendo de 1) qué ofrece la instalación, y 2) las opciones que se le pasan.

probá poniendo
   gcc -print-multi-lib
para ver qué multilibs tenés disponibles. Si tenés una máquina común y corriente, con una instalción de linux común y corriente (ej ubuntu), seguramente tengas la "default" (32 bits) y la de 64bits ( -m64 )
 

En diferentes compiladores:
Por otro lado mencionás que ni siquiera C es binary-compatible.
Esto se traduce a que no existen en el mundo sistemas que utilicen librerías compiladas con diferentes compiladores?

Fijáte el kilombo que tiene q hacer una distribución de linux para poder enviarte un binario y que te ande. Eso lo pueden hacer porque ellos controlan qué tenés instalado. Y a veces así ni anda.
En windows es "aparentemente" más fácil, en que copiás una dll y salís a festejar diciendo eureka eureka con la felicidad del ignorante...

 
O hay ciertos límites dentro de los cuales se puede llamar otras funciones y pasarles parámetros? (y que parámetros y resultados sean tipos estándares o que sigan alguna regla)

Calling conventions. Leé todo lo de arriba y después seguimos. Fijáte lo del empaquetamiento.
A todo esto: por qué querés a tanta costa forzar algo para lo que no fue pensado y para lo que no es natural? (compatibilidad binaria en C)

 

--
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"

Daniel Gutson

unread,
Mar 30, 2012, 3:15:30 PM3/30/12
to cp...@googlegroups.com
Quiero ir más alla de la cuestión técnica con esto.
Compatibilidad binaria es algo anacrónico hoy en día.
Por qué? Porque por un lado está el tema de free software (o indirectamente open source), y por otro el de performance.
Este es exactamente el costo de tener una distribución basada en binarios (como la mayoría), en vez de una tipo gentoo que usa portage (te baja los fuentes y los compila en tu máquina con las opciones más adecuadas a la pc que tenés para aprovechar el hardware al máximo).

Por ejemplo, hay sutilezas aún dentro de los micros de intel que pueden hacer que algo, por forzar a que sea más general, ande mucho más lento y se desperdicien features interesantes.

2012/3/30 Daniel Gutson <daniel...@gmail.com>

Daniel Gutson

unread,
Mar 30, 2012, 3:20:36 PM3/30/12
to cp...@googlegroups.com
y una última aclaración, alineada con separar compilador de linker.

si a.c lo compilaste con gcc X.Y, mientras que b.c lo compilaste con gcc A.B, no interesa, lo interesa es que el linker que uses entienda lo que escupen esas dos versiones del compilador.
Los compiladores no se hablan entre ellos(*), le hablan a los linkers.

(*) esto ya no es exactamente así por LTO, pero eso es un thread aparte.


2012/3/30 Daniel Gutson <daniel...@gmail.com>

Joaquin Duo

unread,
Mar 30, 2012, 5:47:54 PM3/30/12
to cp...@googlegroups.com
On Fri, Mar 30, 2012 at 4:02 PM, Daniel Gutson <daniel...@gmail.com> wrote:


2012/3/30 Joaquin Duo <joa...@gmail.com>
On Fri, Mar 30, 2012 at 12:45 AM, Daniel Gutson <daniel...@gmail.com> wrote:
Joaquín,

  te sugerí que miraras unplugged.googlecode.com, lo viste? Viste los ejemplos?
Sí, lo ví. Debería probarlo con más profundidad.
Ya tengo una versión funcional del sistema de plugins.
Sin embargo está pensado con interfaces en C, para que también se puedan escribir plugins en C.

por qué es algo distinto a lo que propone dlfcn.h ?
No es distinto, lo que debo especificar es el prototipo de las funciones que el plugin debe implementar.
De la misma manera que unplugged crea la función "create_plugin"

(insisto en que deberías ver plugin.h :) )
:-D Ahí lo vi.
 
 


Sí fui poco claro: que no hay name mangling en el soporte a dynamic loading, porque es todo C-calling types. Y porque es una librería de C.
Querés decir que no hay soporte cuando uno busca un símbolo con dlsym?
Porque con nm aparecen todos los símbolos de C++. Me imagino que si una .so usa otra .so de C++, por lo tanto usa los símbolos correspondientes en el linkeo dinámico, no?
 
 
En el siguiente email mencionás que
"  la razón de la existencia del name mangling, es histórica:"
Sé que la tabla de símbolos solo acepta cierto tipo de formato de nombre.

tabla de símbolos? de quién? del compilador? No, en ese caso la tabla de símbolos del compilador no tiene nada que ver. La tabla de símbolos del compilador vive temporalmente mientras compila, y se usa para hacer lookup de símbolos justamente. El name mangling aparece mucho después, al momento de escribir esos símbolos en el archivo objeto para que el linker no se ofenda. Te aconsejo jugar con c++filt.
Me he expresado mal.
Uno puede inspeccionar los símbolos de una librería con el programa "nm".
No sé si le llaman tabla, pero son símbolos.
 
 

xfa distingamos compilador de linker, porque en esta discusión es muy relevante. Yo te puedo romper compatibilidad binaria sólo entre compiladores, sin meter al linker en el medio. Te muestro debajo cómo.
Y decir "gcc" no es suficiente, porque gcc es el "compiler driver", es decir, el programa titiritero que invoca a los distintos componentes del toolchain: preprocesador, compilador, ensamblador, y eventualmente linker.
Tenés razón.

En diferentes compiladores:
Por otro lado mencionás que ni siquiera C es binary-compatible.
Esto se traduce a que no existen en el mundo sistemas que utilicen librerías compiladas con diferentes compiladores?

Fijáte el kilombo que tiene q hacer una distribución de linux para poder enviarte un binario y que te ande. Eso lo pueden hacer porque ellos controlan qué tenés instalado. Y a veces así ni anda.
Sí, como decís, eso es problemático. Lo ideal es que el usuario tenga un experiencia transparente. (que en general lo tiene, pero como decís, a veces no anda)

 
En windows es "aparentemente" más fácil, en que copiás una dll y salís a festejar diciendo eureka eureka con la felicidad del ignorante...
Uhm, sí, realmente me he llevado esta impresión de compatibilidad por cómo trabajan algunos programas de windows.
Ya que mencionás "aparentemente". cómo resuelven el problema? Estandarizan todo, y por lo tanto tiene menos flexibilidad?
 

 
O hay ciertos límites dentro de los cuales se puede llamar otras funciones y pasarles parámetros? (y que parámetros y resultados sean tipos estándares o que sigan alguna regla)

Calling conventions. Leé todo lo de arriba y después seguimos. Fijáte lo del empaquetamiento.
A todo esto: por qué querés a tanta costa forzar algo para lo que no fue pensado y para lo que no es natural? (compatibilidad binaria en C)
No es forzar. Bah, hubiese sido conveniente en algunos casos.
Ejemplo de caso de uso
1- El usuario tiene el núcleo del programa version 1.0 con 100 plugins para ese núcleo.
2- El usuario descarga el núcleo del programa version 2.0 compilado con una nueva versión del compilador.
3- El usuario debería poder reutilizar los 100 plugins que ya tiene compilados.
En este último caso, la compatibilidad binaria no sería un problema por lo menos con mi sistema. (el núcleo no interactúa con las información de los plugins)

En el caso de la interacción entre los plugins sí hay problemas de compatibilidad binaria.
Un caso de uso:
(aclaro: los plugins "tipo de dato" definen los tipos de dato, y los plugins "procesador" hacen operaciones sobre estos datos)
1- El usuario posee un plugin de "tipo de dato" X_v1 y un plugin "procesador" de dato Y_v1
2- El usuario actualiza el plugin de "tipo de dato" X_v1 a X_v2, compilado con otra versión del compilador.
3- El usuario debería poder reutilizar el "procesador" Y_v1 ya compilado

Te resumo mi conclusión con respecto a los plugins:
1- Voy a tener que hacer que el usuario recompile en su máquina, con los pro y contras que tiene esto.
Lo cierto es que soy de la idea que "el código debe acompañar al programa", en el sentido que el usuario debería tener facilidades para cambiar el programa en cualquier entorno. Esto significa que el usuario debe tener un compilador junto con mi sistema. Y en realidad no solo quisiera que tenga un compilador, sino un IDE asociado.

Mi finalidad de las preguntas es conocer los límites de la compatibilidad binaria.
Realmente tenía otra impresión del tema, me has desburrado. :-)

Con respecto a calling conventions, podrías recomendarme algún link/artículo? (voy a googlear igual)

Gracias! :-)

Marcos Bracco

unread,
Mar 30, 2012, 6:02:41 PM3/30/12
to cp...@googlegroups.com
En windows es "aparentemente" más fácil, en que copiás una dll y salís a festejar diciendo eureka eureka con la felicidad del ignorante...

Por?
Windows tiene COM que es justamente una ABI para objetos...


Saludos,
Marcos

Daniel Gutson

unread,
Mar 31, 2012, 3:35:54 PM3/31/12
to cp...@googlegroups.com
2012/3/30 Joaquin Duo <joa...@gmail.com>


On Fri, Mar 30, 2012 at 4:02 PM, Daniel Gutson <daniel...@gmail.com> wrote:


2012/3/30 Joaquin Duo <joa...@gmail.com>
On Fri, Mar 30, 2012 at 12:45 AM, Daniel Gutson <daniel...@gmail.com> wrote:
Joaquín,

  te sugerí que miraras unplugged.googlecode.com, lo viste? Viste los ejemplos?
Sí, lo ví. Debería probarlo con más profundidad.
Ya tengo una versión funcional del sistema de plugins.
Sin embargo está pensado con interfaces en C, para que también se puedan escribir plugins en C.

por qué es algo distinto a lo que propone dlfcn.h ?
No es distinto, lo que debo especificar es el prototipo de las funciones que el plugin debe implementar.
De la misma manera que unplugged crea la función "create_plugin"

(insisto en que deberías ver plugin.h :) )
:-D Ahí lo vi.
 
 


Sí fui poco claro: que no hay name mangling en el soporte a dynamic loading, porque es todo C-calling types. Y porque es una librería de C.
Querés decir que no hay soporte cuando uno busca un símbolo con dlsym?

hay algo mucho más básico:

extern "C" {

void f(float);
void f(char);

}

qué te imaginás q va a pasar..? Yo creo que al linker no le va a resultar simpático.
 
Porque con nm aparecen todos los símbolos de C++. Me imagino que si una .so usa otra .so de C++, por lo tanto usa los símbolos correspondientes en el linkeo dinámico, no?

Pongamos esto en claro de una vez:
  1) tanto binutils en general (y el linker en particular), como el soporte de dynamic loading, no soportan overloading, ni saben qué es name mangling.
  2) el name mangling lo inventa el C++ ANTES de escribir el ELF., y no es otra cosa que a los nombres de las funciones agregarles caracteres a los costados.

Lo que sigue no es que te lo aconsejo, es didáctico nada más, y se desprende de lo de arriba: podrías hacer dlsym y cargar el nombre de una función C++ siempre que le pidas el nombre decorado.
 
 
 
En el siguiente email mencionás que
"  la razón de la existencia del name mangling, es histórica:"
Sé que la tabla de símbolos solo acepta cierto tipo de formato de nombre.

tabla de símbolos? de quién? del compilador? No, en ese caso la tabla de símbolos del compilador no tiene nada que ver. La tabla de símbolos del compilador vive temporalmente mientras compila, y se usa para hacer lookup de símbolos justamente. El name mangling aparece mucho después, al momento de escribir esos símbolos en el archivo objeto para que el linker no se ofenda. Te aconsejo jugar con c++filt.
Me he expresado mal.
Uno puede inspeccionar los símbolos de una librería con el programa "nm".
No sé si le llaman tabla, pero son símbolos.

OK, una cosa es la tabla de símbolos del compilador, y otros son los object symbols, algo élfico (por ELF). Te referís a estos últimos.
 
 
 

xfa distingamos compilador de linker, porque en esta discusión es muy relevante. Yo te puedo romper compatibilidad binaria sólo entre compiladores, sin meter al linker en el medio. Te muestro debajo cómo.
Y decir "gcc" no es suficiente, porque gcc es el "compiler driver", es decir, el programa titiritero que invoca a los distintos componentes del toolchain: preprocesador, compilador, ensamblador, y eventualmente linker.
Tenés razón.

En diferentes compiladores:
Por otro lado mencionás que ni siquiera C es binary-compatible.
Esto se traduce a que no existen en el mundo sistemas que utilicen librerías compiladas con diferentes compiladores?

Fijáte el kilombo que tiene q hacer una distribución de linux para poder enviarte un binario y que te ande. Eso lo pueden hacer porque ellos controlan qué tenés instalado. Y a veces así ni anda.
Sí, como decís, eso es problemático. Lo ideal es que el usuario tenga un experiencia transparente. (que en general lo tiene, pero como decís, a veces no anda)

 
En windows es "aparentemente" más fácil, en que copiás una dll y salís a festejar diciendo eureka eureka con la felicidad del ignorante...
Uhm, sí, realmente me he llevado esta impresión de compatibilidad por cómo trabajan algunos programas de windows.
Ya que mencionás "aparentemente". cómo resuelven el problema? Estandarizan todo, y por lo tanto tiene menos flexibilidad?

Lo explico en otro mail, invitando a otros que saben mucho más del tema. Pero es una cuestión más que nada que las librerías de sistema las compilan "ellos".
 
 

 
O hay ciertos límites dentro de los cuales se puede llamar otras funciones y pasarles parámetros? (y que parámetros y resultados sean tipos estándares o que sigan alguna regla)

Calling conventions. Leé todo lo de arriba y después seguimos. Fijáte lo del empaquetamiento.
A todo esto: por qué querés a tanta costa forzar algo para lo que no fue pensado y para lo que no es natural? (compatibilidad binaria en C)
No es forzar. Bah, hubiese sido conveniente en algunos casos.
Ejemplo de caso de uso
1- El usuario tiene el núcleo del programa version 1.0 con 100 plugins para ese núcleo.
2- El usuario descarga el núcleo del programa version 2.0 compilado con una nueva versión del compilador.
3- El usuario debería poder reutilizar los 100 plugins que ya tiene compilados.
En este último caso, la compatibilidad binaria no sería un problema por lo menos con mi sistema. (el núcleo no interactúa con las información de los plugins)

INSISTO, por última vez: mucho más importante de qué versión de compilador usaste, es qué versión de librerías usaste.
Imagináte que los 100 plugines usen iostream, provista por libstd...x.0
pero tu core v2 usa la y.0. Cuando el sistema operativo cargue el core, en late binding va a resolver y.0. En algún momento se llega a dlopen, la cual detecta dependencia con x.0. Estoy 98% seguro de que va a fallar el dlopen.

Para no volver sobre el tema: te invito a que uses los términos con precisión porque es relevante en la discusión:
toolchain = build system + preprocesador + compilador + ensamblador + linker + librerías de lenguaje + debugger;
como ves, el compilador es sólo un componente del toolchain, y en contexto de este thread, uno mucho menos relevante que las "librerías de lenguaje".
(build system incluye: make por ejemplo, y compiler driver).
En terminología linux hay un montón de paquetes que componen al toolchain: gnumake, gcc, binutils, libstdc++, libc, gdb, etc.
(el dynamic loader no es parte del toolchain, sino del sistema operativo).

Como justamente no hay algo que sea "la versión del toolchain", tenés que especificarla como la lista de las versiones de los paquetes involucrados.
La versión del paquete "gcc" es poco importante para este thread; la versión de binutils es más importante, la versión de libstdc++ y libc son fundamentales.
Casi que te diría que tu problema está acotado a estas dos últimas.
Pero SIEMPRE tenés que tener en cuenta el toolchain completo.

Por ejemplo, si hacés ldd de un .so y ldd del ejecutable, fijáte que las librerías repetidas sean de la misma versión.
 

En el caso de la interacción entre los plugins sí hay problemas de compatibilidad binaria.
Un caso de uso:
(aclaro: los plugins "tipo de dato" definen los tipos de dato, y los plugins "procesador" hacen operaciones sobre estos datos)
1- El usuario posee un plugin de "tipo de dato" X_v1 y un plugin "procesador" de dato Y_v1
2- El usuario actualiza el plugin de "tipo de dato" X_v1 a X_v2, compilado con otra versión del compilador.
3- El usuario debería poder reutilizar el "procesador" Y_v1 ya compilado

Te resumo mi conclusión con respecto a los plugins:
1- Voy a tener que hacer que el usuario recompile en su máquina, con los pro y contras que tiene esto.
Lo cierto es que soy de la idea que "el código debe acompañar al programa", en el sentido que el usuario debería tener facilidades para cambiar el programa en cualquier entorno. Esto significa que el usuario debe tener un compilador junto con mi sistema. Y en realidad no solo quisiera que tenga un compilador, sino un IDE asociado.

Mi finalidad de las preguntas es conocer los límites de la compatibilidad binaria.


Volvé a re-pensar todo esto a partir de lo que te aclaré del toolchain recién. Y por favor, no vuelvas a mencionar "la versión de gcc" porque no te contesto más :)
 
Realmente tenía otra impresión del tema, me has desburrado. :-)

Con respecto a calling conventions, podrías recomendarme algún link/artículo? (voy a googlear igual)

Leéte alguna ABI, por ejemplo en el artículo de wikipedia hay varias referenciadas abajo.
O una clásica: www.x86-64.org/documentation/abi.pdf
 



Gracias! :-)

--
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"

Daniel Gutson

unread,
Mar 31, 2012, 3:39:02 PM3/31/12
to cp...@googlegroups.com
Como siempre hago re-post....

 a ver, aclaro.

No es que te estoy queriendo convencer de que tenés que evitar compatibilidad binaria a toda costa. Se puede lograr si sos cuidadoso, pero como son muchas las cosas q tenés q tener en cuenta, es frágil y fácil de romperse y que sea un dolor de huevos de mantener en cada usuario.

Pero básicamente tendrías que tener en cuenta:

   1- interacción entre los componentes que vos controlás (core y plugines)
   2- interacción entre los componentes que vos controlás y lo que no controlás (las librerías contra las que linkeen tanto el core como los plugines).


Nunca me contestaste lo del empaquetamiento. Sabés a qué me refería entonces?

2012/3/31 Daniel Gutson <daniel...@gmail.com>

Joaquin Duo

unread,
Mar 31, 2012, 4:36:20 PM3/31/12
to cp...@googlegroups.com
On Sat, Mar 31, 2012 at 4:35 PM, Daniel Gutson <daniel...@gmail.com> wrote:

Volvé a re-pensar todo esto a partir de lo que te aclaré del toolchain recién. Y por favor, no vuelvas a mencionar "la versión de gcc" porque no te contesto más :)
En mi último email nunca mencioné a gcc.
-Una cosa es la compatibilidad a nivel de linkeo.
-Otra cosa es la compatibilidad binaria.
Por qué interpretás que en mi último email mezclo ambos conceptos?
Los casos de uso son de compatibilidad binaria, dejando de lado los problemas de linkeo. (no los tengas en cuenta. En algunos casos se pueden arreglar, pero tengo que sacarme una duda antes de contestar sobre esto)

Daniel Gutson

unread,
Mar 31, 2012, 4:47:08 PM3/31/12
to cp...@googlegroups.com


2012/3/31 Joaquin Duo <joa...@gmail.com>

On Sat, Mar 31, 2012 at 4:35 PM, Daniel Gutson <daniel...@gmail.com> wrote:

Volvé a re-pensar todo esto a partir de lo que te aclaré del toolchain recién. Y por favor, no vuelvas a mencionar "la versión de gcc" porque no te contesto más :)
En mi último email nunca mencioné a gcc.

bueno gcc no pero decís

"2- El usuario descarga el núcleo del programa version 2.0 compilado con una nueva versión del compilador."

...

"2- El usuario actualiza el plugin de "tipo de dato" X_v1 a X_v2, compilado con otra versión del compilador."


El impacto en cambio de versión del compilador puede ser si optimiza más u optimiza menos un loop. Punto. Absolutamente irrelevante para vos. No se menciona más. No van a cambiar las name mangling rules en la práctica por ejemplo.


 
-Una cosa es la compatibilidad a nivel de linkeo. 
-Otra cosa es la compatibilidad binaria.
Por qué interpretás que en mi último email mezclo ambos conceptos?
Los casos de uso son de compatibilidad binaria, dejando de lado los problemas de linkeo. (no los tengas en cuenta. En algunos casos se pueden arreglar, pero tengo que sacarme una duda antes de contestar sobre esto)

--
¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido este mesaje por error.
En caso de duda visita "http://groups.google.com/group/cppba"

Daniel Gutson

unread,
Mar 31, 2012, 4:56:19 PM3/31/12
to cp...@googlegroups.com
Flaco, hagamos algo,
si querés seguir charlando de esto, antes leé, y después seguimos.
Te aconsejo leer la especificación de ELF. Es áspero, pero yo me lo tuve que morfar en su momento (hace demasiado, encima vos estás haciendo q yo tenga q sacar telaraña de mi mente); vos también te lo podés morfar. Ahí te va a responder dudas que ni siquiera se te ocurren ahora.

Como un acto de inmensa generosidad te paso el link:

No pienso responder más este thread hasta que no pase el tiempo que estimo que te tomará leerlo.

Sé feliz.

   Daniel.


2012/3/31 Daniel Gutson <daniel...@gmail.com>
Reply all
Reply to author
Forward
0 new messages