Lista de problemas de C ++ ABI

He visto mucha discusión sobre cómo C ++ no tiene un ABI estándar del mismo modo que C. Tengo curiosidad sobre cuáles son exactamente los problemas. Hasta ahora, he venido con

  1. Nombre mangling
  2. Manejo de excepciones
  3. RTTI

¿Hay algún otro problema ABI relacionado con C ++?

La parte superior de mi cabeza:

C ++ específico:

  • Donde se puede encontrar el parámetro ‘this’.
  • Cómo se llaman las funciones virtuales
    • es decir, ¿usa un vtable u otro
    • ¿Cuál es el diseño de las estructuras utilizadas para implementar esto?
  • Cómo se manejan múltiples definiciones
    • Instancias de plantillas múltiples
    • Funciones en línea que no estaban en línea.
  • Objetos de duración de almacenamiento estático
    • Cómo manejar la creación (en el scope global)
    • Cómo gestionar la creación de la función local (cómo se agrega a la lista de destructor)
    • Cómo manejar la destrucción (destruir en el orden inverso de la creación)
  • Usted menciona excepciones. Pero también cómo se manejan las excepciones fuera de main ()
    • es decir, antes o después de main ()

Genérico.

  • Lugares para pasar los parámetros
  • Ubicación del valor de retorno
  • Alineación de miembros
  • Relleno
  • Uso de registro (qué registros se conservan que son cero)
  • tamaño de tipos primitivos (como int)
  • formato de tipos primitivos (formato de punto flotante)

El gran problema, en mi experiencia, es la biblioteca estándar de C ++. Incluso si tuviera un ABI que dicte cómo se debe diseñar una clase, los diferentes comstackdores proporcionan diferentes implementaciones de objetos estándar como std::string y std::vector .

No estoy diciendo que no sería posible estandarizar el diseño interno de los objetos de la biblioteca C ++, solo que no se ha hecho antes.

Lo más parecido que tenemos a un estándar de C ++ ABI es el Itanium C ++ ABI :

este documento está escrito como una especificación genérica, para ser utilizado por C ++> implementaciones en una variedad de architectures. Sin embargo, contiene> material específico del procesador para el IANium 64-bit ABI, identificado como tal. ”

El documento de GCC explica el soporte de este ABI para C ++:

Comenzando con GCC 3.2, las convenciones binarias de GCC para C ++ se basan en un ABI de C ++ escrito, independiente del proveedor, diseñado para ser específico de Itanium de 64 bits, pero también incluye especificaciones genéricas que se aplican a cualquier plataforma. Este C ++ ABI también es implementado por otros proveedores de comstackdores en algunas plataformas, notablemente sistemas GNU / Linux y BSD.

Tal como lo señaló @Lindydancer, también debe usar el mismo ciclo de biblioteca / tiempo de ejecución estándar de C ++.

Un estándar ABI para cualquier idioma realmente debe provenir de una plataforma determinada que quiera respaldar tal cosa. Los estándares de lenguaje especialmente C / C ++ realmente no pueden hacer esto por muchas razones, pero principalmente porque tal cosa haría que el lenguaje sea menos flexible y menos portátil y, por lo tanto, menos utilizado. C realmente no tiene un ABI definido, pero muchas plataformas definen (directa o indirectamente) uno. La razón por la que esto no está sucediendo con C ++ es porque el idioma es mucho más grande y los cambios se realizan con más frecuencia. Sin embargo, Herb Sutter tiene una propuesta muy interesante sobre cómo obtener más plataformas para crear ABI estándar y cómo los desarrolladores pueden escribir código que usa el ABI de forma estándar:

https://isocpp.org/blog/2014/05/n4028

Señala cómo C ++ tiene una forma estándar de vincularse a una plataforma C ABI, pero no a un C ++ ABI a través del exterior “C”. Creo que esta propuesta podría ser de gran ayuda para permitir que las interfaces se definan en términos de C ++ en lugar de C.

He visto mucha discusión sobre cómo C ++ no tiene un ABI estándar del mismo modo que C.

¿Qué estándar C ABI? El apéndice J en el estándar C99 tiene 27 páginas. Además del comportamiento indefinido (y algunas implementaciones dan a UB un comportamiento bien definido), cubre el comportamiento no especificado, el comportamiento definido en la implementación, el comportamiento específico del entorno local y las extensiones comunes.