visual studio how from compiler compile code c++ c visual-c++ gcc data-structures

how - visual studio c++ compiler linux



Equivalente a Visual C++ de__attribute__ de GCC((__packed__)) (6)

Para algunos compiladores, hay un especificador de empaquetado para las estructuras, por ejemplo ::

RealView ARM compiler has "__packed" Gnu C Compiler has "__attribute__ ((__packed__))" Visual C++ has no equivalent, it only has the "#pragma pack(1)"

Necesito algo que pueda poner en la definición de estructura .

¿Alguna información / truco / sugerencia? TIA ...


¿Por qué necesitas algo para entrar en la estructura?

Creo que #pragma pack(1) es el mismo, ¿o me falta algo?

Puedes hacerlo:

struct Foo { #pragma pack(push, 1) int Bar; #pragma pack(pop) };

Pero se ve feo.


No conozco una forma ingeniosa de hacerlo, pero posiblemente podrías hacer algo horrible como este:

#include "packed.h" struct Foo { /* members go here */ } PACKED; #include "endpacked.h"

Luego, para MSVC, packed.h:

#define PACKED #pragma pack(push,1)

endpacked.h

#pragma pack(pop) #undef PACKED

Para gcc, packed.h:

#define PACKED __attribute__ ((__packed__))

endpacked.h:

#undef PACKED

Fundamentalmente, el embalaje depende demasiado de la plataforma. Supongamos que su estructura empaquetada tiene campos de 8 bits y considera algún sistema con un byte de 16 bits. No puede tener una estructura que represente los datos simplemente empaquetando; debería saber cómo los bytes de 8 bits se convierten en bytes de 16 bits cuando se transfieren entre los dos sistemas. La estructura en la máquina de 16 bits puede necesitar campos de bits, en cuyo caso debe saber cómo la implementación los establece.

Entonces, si el código está destinado a ser generalmente portátil, puede que simplemente tenga que definir las estructuras empaquetadas que necesita en una sección específica de la plataforma de su archivo de encabezado. O más bien, estructure su código para que un puerto futuro pueda hacer eso si es necesario.


Otra solución, dependiendo de los compiladores que necesita admitir, es notar que GCC ha respaldado los pragmas de empaquetado al estilo Microsoft al menos desde la versión 4.0.4 (la documentación en línea está disponible en gnu.org para las versiones 3.4.6 y 4.0.4). - los pragmas no se describen en el primero y están en el segundo). Esto le permite usar #pragma pack(push,1) antes de una definición de estructura y #pragma pack(pop) después de la definición y se compilará en cualquiera de ellos.


Puede definir PACK como este para GNU gcc

#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))

y así para Visual C ++:

#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )

Y úsalo así:

PACK( struct myStruct { int a; int b; });


Puede hacerlo al revés, ya que GCC es compatible con los pragmas relacionados con el paquete VC ++. Mire here para más información.

Extraer...

Para la compatibilidad con los compiladores de Microsoft Windows, GCC admite un conjunto de directivas #pragma que cambian la alineación máxima de los miembros de las estructuras (distintos de los campos de bits de ancho cero), las uniones y las clases definidas posteriormente. Siempre se requiere que el valor n de debajo sea una pequeña potencia de dos y especifica la nueva alineación en bytes.

#pragma pack(n) simplemente establece la nueva alineación.

#pragma pack() establece la alineación con la que estaba en vigor cuando se inició la compilación (ver también la opción de línea de comando -fpack-struct[=<n>] ver Opciones de código genérico).

#pragma pack(push[,n]) empuja la configuración de alineación actual en una pila interna y luego establece opcionalmente la nueva alineación.

#pragma pack(pop) restaura la configuración de alineación a la guardada en la parte superior de la pila interna (y elimina esa entrada de la pila).

Tenga en cuenta que #pragma pack([n]) no influye en esta pila interna; por lo tanto, es posible tener #pragma pack(push) seguido de múltiples #pragma pack(n) instancias y finalizado por un solo #pragma pack(pop) .

Algunos objetivos, por ejemplo, i386 y powerpc, son compatibles con ms_struct #pragma que establece una estructura como documentado __attribute__((ms_struct)) .

#pragma ms_struct on activa el diseño de las estructuras declaradas.

#pragma ms_struct off desactiva el diseño de las estructuras declaradas.

#pragma ms_struct reset vuelve al diseño predeterminado.


Sé que esta pregunta es antigua ahora, pero creo que hay una solución mejor que las publicadas anteriormente. Es posible poner el pragma en el caso de MSVC en la línea de declaración de estructura después de todo. Considera lo siguiente:

#ifdef _MSC_VER # define PACKED_STRUCT(name) / __pragma(pack(push, 1)) struct name __pragma(pack(pop)) #elif defined(__GNUC__) # define PACKED_STRUCT(name) struct __attribute__((packed)) name #endif

Entonces esto se puede usar así:

typedef PACKED_STRUCT() { short a; int b } my_struct_t; PACKED_SRUCT(my_other_struct) { short a; int b };

etc.

La clave aquí es que el uso del __pragma solo necesita estar alrededor de la línea de declaración de la estructura. Esto necesita incluir el nombre de la estructura si se le da uno, de ahí que el nombre sea un parámetro para la macro. Por supuesto, esto es fácil de extender a enum / class, ¡que dejaré como ejercicio para el lector!

El programa de prueba en la documentación de la página MSDN del paquete es útil para verificar esto.

EDITAR

Resulta que en mis pruebas estaba usando el compilador Intel en Windows. Usando icl.exe, este enfoque funciona sin problemas, pero con el compilador de Microsoft (cl.exe), no (probado con 2010 y 2013).