Author Topic: Interesting problem with #pragma pack(1)  (Read 7200 times)

ajs15822

  • Not-a-newbie
  • *
  • Posts: 10
  • Karma: 3
  • Naked to the Visible Eye
    • View Profile
Interesting problem with #pragma pack(1)
« on: December 04, 2006, 11:19:59 PM »
I've never had this problem working in gcc before but when I began to work on my project in Visual Studio 2005, I encountered this warning:
Code: [Select]
alignment changed after including header, may be due to missing #pragma pack(pop)
Here is an excerpt of the offending code:
Code: [Select]
#pragma pack(1)
struct client_LoginPacket
{
unsigned char packetID;
char username[16];
char password[16];

void setupPacket()
{
packetID = ID_CLIENT_LOGIN;
}

void initializeData(char *_username, char *_password)
{
memcpy(username,_username,16);
memcpy(password,_password,16);
}
};

Apparently the '#pragma pack(1)' directive was bleeding through. I initially paid little attention to this warning and coded a considerable chunk of my application without testing this header in-depth. Fast-forward a few days, I ran into a major problem with the following error while debugging:
Code: [Select]
Run-Time Check Failure #2 - Stack around the variable '_player' was corrupted
After two days of tracing code, I found nothing. On a whim, I began to comment out a few headers to see if the problem lied elsewhere; it did. The earlier warning about 'alignment changed' must have been doing some pretty funky things to the parts of my code where the offending header was included. I realized I needed to change the #pragma directive to something a little more controlled.

I changed '#pragma pack(1)' to '#pragma pack(push, 1)' before every struct declaration and I also added '#pragma pack(pop)' right before the end of every struct.

Thus, my earlier code example now looks like this:
Code: [Select]
#pragma pack(push,1)
struct client_LoginPacket
{
unsigned char packetID;
char username[16];
char password[16];

void setupPacket()
{
packetID = ID_CLIENT_LOGIN;
}

void initializeData(char *_username, char *_password)
{
memcpy(username,_username,16);
memcpy(password,_password,16);
}
#pragma pack(pop)
};

Moral of the story: Make sure you have a '#pragma pack(pop)' for every '#pragma pack(push, 1)'

 ;)