can't #define #pragma pack?

Started by
14 comments, last by Falken42 17 years, 8 months ago
Hello all, I am trying to find a way to set up structure packing using #define macros while also being compiler-independant. Ideally, something like this would be great:
MYSTRUCTPACK(1) struct
{
    char foo;
    int bar;
} hoge;

However, MSVC (and other compilers) use a #pragma with a push and pop syntax, rather than a _declspec like they use for alignment, so I've resigned myself that this is probably the best I'd ever be able to do:
MYSTRUCTPACK_BEGIN(1)

struct
{
    char foo;
    int bar;
} hoge;

MYSTRUCTPACK_END()


Unfortunately, MSVC doesn't like me using a #define to declare #pragma pack:
#define MYSTRUCTPACK_BEGIN(x)     #pragma pack(push, x)    // error C2162: expected macro formal parameter
After much fruitless searching on Google, I did manage to find one thread here on gamedev where Null and Void pointed out how CPT handles this issue. The only problem with using a #include to wrap a structure is that I wouldn't be able to specify the desired packing (1, 2, 4, 8, 16, etc) unless I created multiple include files each with a different values. That post was made back in 2002. Is there any better way to do this 4 years later that I'm just not aware of?
Advertisement
You cannot define a macro which uses the preprocessor.
Quote:Original post by Roboguy
You cannot define a macro which uses the preprocessor.


What?

// ---------------------------------------------------------------------------// use the preprocessor to turn a symbol into a string#define STR(x) #x#define STRING(x) STR(x)




bpoint, it might require using a set of 8 headers - before and after for each possibility.


"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by LessBread
Quote:Original post by Roboguy
You cannot define a macro which uses the preprocessor.


What?

*** Source Snippet Removed ***


I meant you can't issue preprocessor directives, like #pragma in a macro.
Okay, I've played with it some more and managed to get a bit farther. MSDN docs say:
Quote:Following #pragma, write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.


So I can whip up something like this:

#define MYPACK_BEGIN(x)				pack(push, x)#define MYPACK_END					pack(pop)#pragma MYPACK_BEGIN(1)struct{    char foo;    int bar;} hoge;#pragma MYPACK_END


This would also work for other compilers, assuming that they allow macro substitution after the #pragma. However, this leaves out GCC which decided to be "different" and use the __attribute__ syntax instead of a #pragma...

I then decided to see if I could use string substitution in a macro to create a header filename like so:

#define MYPACK2(x)					"PackHeader" #x ".h"#include MYPACK2(4)      // warning C4067: unexpected tokens following preprocessor directive - expected a newline                          // fatal error C1083: Cannot open include file: 'PackHeader': No such file or directory


But this doesn't seem to work either.

Does anyone have any other ideas (even if they are hackish)? Or am I just going to have to break down and make include files for each packing alignment I need, like LessBread has suggested?

Thanks for the tips, guys.
Quote:Original post by bpoint
However, this leaves out GCC which decided to be "different" and use the __attribute__ syntax instead of a #pragma...


No it didn't, #pragmas are compiler-specific.
Quote:Original post by Roboguy
No it didn't, #pragmas are compiler-specific.


Indeed they are. However, GCC certainly could have implemented structure packing the same way every other compiler has done it, rather than being different.

Actually, I prefer the __attribute__ syntax myself. But unfortunately everyone else uses #pragma already...
Quote:Original post by Roboguy
Quote:Original post by LessBread
Quote:Original post by Roboguy
You cannot define a macro which uses the preprocessor.


What?

*** Source Snippet Removed ***


I meant you can't issue preprocessor directives, like #pragma in a macro.


It seems to me that #pragma is a compiler directive not a preprocessor directive. However, microsoft appears to categorizes it as a preprocessor directive, which might explain why bpoint ran in to trouble with MSVC. I don't have a copy of the standard at hand to check, maybe someone else does.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
It seems that since gcc-4.0, gcc supports #pragma pack for compatibility with Win32.

If that's the case then all I need to is ensure MetroWorks and GCC will allow me to #define the text after the pragma. I'm not at home now, so I'll try testing this theory later tonight.
Uhm, it seems you didn't read the MSDN, or i am missing something... __declspec(align(X)) seems to be the thing you are looking for, or am i wrong?


On the other hand, if you want to go with includes, then your attempt (bellow) is wrong.
#define MYPACK2(x) "PackHeader" #x ".h"#include MYPACK2(4)


What you should do is something like this:
#define		STRINGIZE(X) #X#define		PACK(X) STRINGIZE(pack##X##.h)#define		PACK_END "packend.h"


EDIT: fixed the link...

EDIT2: added includes

[Edited by - Paulius Maruska on August 17, 2006 3:32:33 AM]

This topic is closed to new replies.

Advertisement