Visual C++ equivalent of GCC's __attribute__ ((__packed__))

C++CVisual C++GccData Structures

C++ Problem Overview


For some compilers, there is a packing specifier for structs, for example ::

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

I need something that I can put into the struct definition.

Any info/hack/suggestion ? TIA...

C++ Solutions


Solution 1 - C++

You can define PACK like as follows for GNU GCC and MSVC:

#ifdef __GNUC__
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
#endif

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

And use it like this:

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

Solution 2 - C++

I don't know a slick way of doing it, but you could possibly do something horrible like this:

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

Then for MSVC, packed.h:

#define PACKED
#pragma pack(push,1)

endpacked.h

#pragma pack(pop)
#undef PACKED

For gcc, packed.h:

#define PACKED __attribute__ ((__packed__))

endpacked.h:

#undef PACKED

Fundamentally, packing is too platform-dependent. Suppose your packed struct has 8-bit fields in it, and consider some system with a 16-bit byte. It can't have a struct representing your data just by packing - you'd have to know how 8-bit bytes are converted to 16-bit bytes when transferred between the two systems. The struct on the 16bit machine might need bitfields, in which case you'd have to know how the implementation lays them out.

So if the code is intended to be generally portable, you may just have to define whatever packed structures you need in a platform-specific section of your header file. Or rather, structure your code so that a future port can do that if it has to.

Solution 3 - C++

I know this question is old now, but I believe there is a better solution than those posted earlier. It is possible to put the pragma in the MSVC case in the struct declaration line after all. Consider the following:

#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

Then this can be used like so:

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

etc.

The key here is that the use of the __pragma only needs to be around the declaration line of the struct. This needs to include the struct name if it is given one, hence the name being a parameter to the macro. Of course, this is easy to extend to enum/class, which I'll leave as an exercise to the reader!

The test program on the pack documentation MSDN page is useful to verify this.

EDIT

It turns out in my testing I was using the Intel Compiler on Windows. Using icl.exe this approach works without a problem, but with the Microsoft compiler (cl.exe), it does not (tested with 2010 and 2013).

Solution 4 - C++

You can do it the other way round since GCC supports the VC++ pack related pragmas. Look here for more information.

Extract...

> For compatibility with Microsoft Windows compilers, GCC supports a set > of #pragma directives which change the maximum alignment of members of > structures (other than zero-width bitfields), unions, and classes > subsequently defined. The n value below always is required to be a > small power of two and specifies the new alignment in bytes. > > #pragma pack(n) simply sets the new alignment. > > #pragma pack() sets the alignment to the one that was in effect when > compilation started (see also command line option > -fpack-struct[=<n>] see Code Gen Options). > > #pragma pack(push[,n]) pushes the current alignment setting on an > internal stack and then optionally sets the new alignment. > > #pragma pack(pop) restores the alignment setting to the one saved at > the top of the internal stack (and removes that stack entry). > > Note that #pragma pack([n]) does not influence this internal stack; > thus it is possible to have #pragma pack(push) followed by multiple > #pragma pack(n) instances and finalized by a single #pragma pack(pop). > > Some targets, e.g. i386 and powerpc, support the ms_struct #pragma > which lays out a structure as the documented __attribute__((ms_struct)). > > #pragma ms_struct on turns on the layout for structures declared. > > #pragma ms_struct off turns off the layout for structures declared. > > #pragma ms_struct reset goes back to the default layout.

Solution 5 - C++

Another solution, depending what compilers you need to support, is to notice that GCC has supported the Microsoft-style packing pragmas since at least version 4.0.4 (the online documentation is available at gnu.org for versions 3.4.6 and 4.0.4 - the pragmas are not described in the former and are in the latter). This lets you just use #pragma pack(push,1) before a structure definition and #pragma pack(pop) after the definition and it will compile in either.

Solution 6 - C++

Why do you need something to go in the struct?

I think #pragma pack(1) is the same, or am I missing something?

You can do this:

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

But it looks ugly.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMalkocogluView Question on Stackoverflow
Solution 1 - C++StephView Answer on Stackoverflow
Solution 2 - C++Steve JessopView Answer on Stackoverflow
Solution 3 - C++Sam JansenView Answer on Stackoverflow
Solution 4 - C++AutodidactView Answer on Stackoverflow
Solution 5 - C++TomView Answer on Stackoverflow
Solution 6 - C++graham.reedsView Answer on Stackoverflow