Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Alignment of User-defined Data 1

Status
Not open for further replies.

porto99

Technical User
Nov 1, 2004
96
GB
I am trying to define a structure such that its not padded out to the nearest byte.

I did think that the directive #pragma pack(1) meant that across a 32 bit (4 byte) boundry all the bits are used.

e.g.


#pragma pack(1)

typedef __declspec(align(1)) struct{
unsigned long a1_t12_word_0_block_label : 12;
unsigned long a1_t12_word_0_spare_825_12 : 2;
unsigned long a1_t12_word_0_hset_ld_succ : 2;
unsigned long a1_t12_word_1_hqi_a_net : 8;
unsigned long a1_t12_word_1_hqi_b_net : 8;
unsigned long a1_t12_word_2_hqii_na : 8;
unsigned long a1_t12_word_2_hqii_non_na : 8;
unsigned long a1_t12_word_3_hqii_fmt1 : 8;
unsigned long a1_t12_word_3_hqii_fmt2 : 8;
unsigned long a1_t12_word_4_hqii_fmt3 : 8;
unsigned long a1_t12_word_4_hqii_fmt4 : 8;
unsigned long a1_t12_word_5_hqii_fmt5 : 8;
unsigned long a1_t12_word_5_hqii_fmt6 : 8;
unsigned long a1_t12_word_6_sat_na : 8;
unsigned long a1_t12_word_6_sat_non_na : 8;
unsigned long a1_t12_word_7_sat_t40_na : 8;
unsigned long a1_t12_word_7_sat_t40_non_na : 8;
unsigned long a1_t12_word_8_hqii_fmt7 : 8;
unsigned long a1_t12_word_8_hqii_fmt8 : 8;
}a1_VUHF1_T12;

The size of this structure is 20 bytes. It should be 18 bytes, how can I get it to be 18 bytes?
 
What are you going to do with it once you've packed it to 18 bytes?

If you're trying to pull apart some external bit-packed structure, then bit fields are NOT the answer.

The answer to your immediate question is make everything an [tt]unsigned short[/tt], which in VC6 produces a size of 18 bytes.

--
 
What I do is form a union with a buffer

unsigned short buffer[32];

So that I can modify a single field, but send the message by using the buffer.

The code did work in VS 2003; just a problem with VS 2005; or have I got a setting wrong or just do as you say - IT WORKS!

But don't know why!

Many thanks.
 
That's what happens when you rely on non-standard behaviour.

Sometimes it works, then following any random upgrade or whatever, it stops working.

If you want an answer that always works, then don't use bit-fields for this particular problem.


--
 
I've never used bit-fields before, but I thought they were part of the standard?

Since all but 3 of the elements of the struct are 8 bits, couldn't they be declared as unsigned char?
 
Bit fields are standard.
What isn't standard includes
- whether they start in the LSB or the MSB
- how they're padded and aligned
- what the underlying storage unit is

Great if all you're dealing with is internal data, but pretty much useless if you're trying to map some external data format.


--
 
Thanks Salen, that works fine.

But would like to understand why in VS 2003 unsigned long worked, but with VS 2005 I have to change to unsigned short.

Many thanks,

Andy.
 
> But would like to understand why in VS 2003 unsigned long worked
No idea - ask microsoft.

Seriously, if you play with implementation specific behaviour, expect to get burnt occasionally.

> unsigned long a1_t12_word_0_spare_825_12 : 2;
Why did you ever say long in the first place, given that there are only two bits?
Bitfields should be specified as either
Code:
signed int foo : 2;
unsigned int foo : 2;

Qualifiers like 'short' and 'long' signify more about the size of the data type than is necessary, and maybe the compiler picks up on this when trying to align things.

But I'll say it again - bitfields for this application are inherently non-portable. There's no guarantee that it won't break again in the future.

--
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top