2012-04-24 6 views
9

Suponiendo que el siguiente archivo de encabezado corresponde, por ejemplo, a una biblioteca compartida. La función exportada toma un puntero a una estructura personalizada definida en esta cabecera:C struct alineación y portabilidad en los compiladores

// lib.h 

typedef struct { 
    char c; 
    double d; 
    int i; 
} A; 

DLL_EXPORT void f(A* p); 

Si la biblioteca compartida se construye utilizando un compilador y luego se utiliza a partir del código C integrado con otro compilador podría no funcionar debido a una diferente alineación de memoria, como Memory alignment in C-structs sugiere. Entonces, ¿hay alguna manera de hacer que la definición de mi estructura sea portátil en diferentes compiladores en la misma plataforma?

Estoy interesado específicamente en la plataforma Windows (aparentemente no tiene un ABI bien definido), aunque sería curioso conocer otras plataformas también.

+3

No, a menos que alguien te haya garantizado eso. –

+3

Sin duplicado. Al menos no de la pregunta seleccionada. Este puede sostenerse por sí mismo. –

+1

¿Alguna pregunta que contenga palabras "struct alignment" es automáticamente un duplicado de esa otra pregunta, incluso cuando no tiene nada que ver con eso? –

Respuesta

11

TL; DR en la práctica, debería estar bien.

El estándar C no define esto, pero una plataforma ABI generalmente lo hace. Es decir, para una arquitectura de CPU y un sistema operativo dados, puede haber una definición de cómo C se correlaciona con el ensamblado, lo que permite que diferentes compiladores interoperen.

Alineación de estructuras no es lo único que una plataforma ABI tiene que definir, también tiene convenciones de llamadas a funciones y cosas por el estilo.

C++ lo hace aún más complejo y el ABI tiene que especificar vtables, excepciones, renombrado de nombres, etc.

En Windows Me parece que son múltiples C++ ABIs dependiendo del compilador pero C es sobre todo compatible a través de compiladores. Podría estar equivocado, no soy un experto en Windows.

Algunos enlaces:

De todos modos el resultado final es que usted está buscando para su garantía en el especificación ABI de plataforma/compilador, no el estándar C.

+0

Gracias por su esfuerzo, aunque mi pregunta no se refiere a C++ en absoluto. Sé acerca de ABI, esa es la razón por la que marqué la pregunta específica de Windows ya que nunca supe de las especificaciones de ABI en Windows. –

+0

@ 7vies: C también tiene un ABI (piense en las diferentes convenciones de llamadas, cdecl, stdcall, fastcall). Es solo que para C los diferentes compiladores son generalmente los mismos (al menos para las convenciones de llamadas "normales"), aunque solo sea para que coincida con lo que el sistema operativo espera para las llamadas al sistema. Con C++ los diferentes compiladores a menudo * no * aceptan la misma API, especialmente para nombres externos. –

+0

@MichaelBurr, como nota al margen, wikipedia dice que estas son _x86_ convenciones, ¿se usan también en otras arquitecturas? Soy consciente de los problemas de C++, es por eso que estoy preguntando cómo hacer que funcione en C. Las convenciones de llamada realmente ayudan a definir una interfaz portátil, pero no resuelven mi problema con la alineación de la estructura. –

1

No solo eso no está garantizado, pero incluso si usa el mismo compilador, puede haber diferencias debido a los diferentes modificadores de compilación utilizados en la compilación, o si usa versiones diferentes del mismo compilador y los mismos modificadores (sucedidos en un compilador integrado en el que trabajé).

Debe asegurarse de que las estructuras se representen exactamente igual, use interruptores, #pragmas, lo que le proporcionen los compiladores.

Mi consejo: mantenerse alejado de todo esto. Pase sus argumentos en la función, no envueltos dentro de una estructura.

E incluso en esta forma simple, si se trata de dos compiladores, no es trivial. Debe asegurarse de que un int tome la misma cantidad de bytes, por ejemplo. También llamar a conevntion - orden de los argumentos - de izquierda a derecha o de derecha a izquierda - puede diferir entre compilador.

3

La única forma de saberlo con certeza es consultando la documentación de los compiladores en cuestión.Sin embargo, generalmente es el caso de que el diseño de C struct (excepto, como usted dice, para los campos de bits) está definido por una descripción ABI para el entorno que está utilizando, y los compiladores de C tenderán a seguir el ABI nativo.

Cuestiones relacionadas