Unity can't #define #pragma pack?

Recommended Posts

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?

Share on other sites
You cannot define a macro which uses the preprocessor.

Share on other sites
Quote:
 Original post by RoboguyYou 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.

Share on other sites
Quote:
Original post by LessBread
Quote:
 Original post by RoboguyYou 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.

Share on other sites
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.

Share on other sites
Quote:
 Original post by bpointHowever, 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.

Share on other sites
Quote:
 Original post by RoboguyNo 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...

Share on other sites
Quote:
Original post by Roboguy
Quote:
Original post by LessBread
Quote:
 Original post by RoboguyYou 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.

Share on other sites
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.

Share on other sites
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...

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

Share on other sites
Quote:
 Original post by Paulius MaruskaUhm, 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?

Structure packing is not the same as alignment.

Structure packing ensures that variables within a structure are aligned to a specific memory address. In my example above, sizeof(hoge) would be 5 if packing was set to 1, or 8 if packing was set to 4.

Alignment (using __declspec) is what aligns the variable itself to a specific memory address. For example, I could align my structure to 16 bytes, so that anywhere it was used the address would be properly aligned.

Alignment can also be specified along with packing, so I could feasibly have a 5 byte sized struct that is 16 byte aligned in memory.

Hope this helps. :)

Share on other sites
You can use _Pragma operator to do this. It is defined in standard (#16.9 Pragma operator).
I have tested it with GCC 4.2.0,4.0.2,4.1.0,3.4.5 and 3.3.6 and it works perfectly

#include <cstdio>#define PACK _Pragma("pack(push,1)")#define UNPACK _Pragma("pack(pop)")PACKstruct MyStruct {	char m_test[3];	int m_test2;	short m_test3;};UNPACKint main(void) { 	printf("sizeof(struct MyStruct): %u\n",sizeof(struct MyStruct));	return 0;}

Share on other sites
Quote:
 Original post by bpointStructure packing is not the same as alignment.<...>Hope this helps. :)

Sorry, i'l note that for the future.

Quote:
 Original post by APYou can use _Pragma operator to do this. It is defined in standard (#16.9 Pragma operator).I have tested it with GCC 4.2.0,4.0.2,4.1.0,3.4.5 and 3.3.6 and it works perfectly

It doesn't work in MSVC8 - i've tested it...

So anyway, you can still use something like this (as in my previous post):
#define		STRINGIZE(X) #X#define		PACK(X) STRINGIZE(pack##X##.h)#define		PACK_END "packend.h"#include PACK(2)struct MyStruct {  int x, y, z;  double a, b, c;};#include PACK_END

Note, however, Visual C++ will issue a warning C4103 if header changes packing. Don't know if other compilers complains about it.

Share on other sites
That would be an absolutely ideal solution if VS2005 (and everybody else) supported it...
Quote:
 error C4430: missing type specifier - int assumed. Note: C++ does not support default-interror C2440: 'initializing' : cannot convert from 'const char [13]' to 'int'error C2143: syntax error : missing ';' before ''error C2448: '_Pragma' : function-style initializer appears to be a function definition

Unfortunately I can't just make a special case for GCC since I need to have a #pragma before the #defined pack macro.

Maybe the next generation of compilers will have a better (and more standardized) way of handling this. But I'm not holding my breath. :)

Share on other sites
I belive Microsoft has several headers called things like "pshpk8" and "pshpk16" and so on, which does exactly what you described for #includes.

Personally, I'd just go with the #includes, it's probably easiest.

Share on other sites
Quote:
 Original post by Evil StevePersonally, I'd just go with the #includes, it's probably easiest.

Yep, that really looks like the best choice. Since CodeWarrior uses #pragma option align=[some text], I wouldn't be able to properly set the structure packing with the MetroWerks compiler. Also using headers allows me to disable that pesky warning under MSVC. :)

Thanks to Paulius Maruska! I didn't realize my preprocessor stringizations were wrong.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• Forum Statistics

• Total Topics
627738
• Total Posts
2978881
• Similar Content

• By KARTHI
• By KARTHI
Currently I using makehuman to make a 3d models but I am not satisfied with that model. If any use this please reply about the quality and details of models.
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔
• By KARTHI
I planned to make a space game so I need a knowledge about 3d planet making so anyone help me to make it possible
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔
• By KARTHI
I planned to make a game like star citizen. In this game player can travel through the space ,explore the planets, Hunt the different creatures, drive the space ship, explore different regions in universe, destroy the space stations and also player can go anywhere in the universe and meet aliens and so on
Did you like this idea?
Please give me reply so that I can easily understand what you want.
🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔🤔

• Your home planet was attacked. Now you have to use your spaceship to battle the invaders. Powerful 3D arcade with outer space background. Very addictive. Good luck!