question

DarabanStefanRBROEES-5020 avatar image
0 Votes"
DarabanStefanRBROEES-5020 asked DarabanStefanRBROEES-5020 commented

#pragma pack(1) is not recognized in C/C++ for x86 compiler

We have the following pragma and the bits are not properly packed in this 32 bits application. #pragma pack(1) is not recognized as a directive.

pragma pack(1)

typedef struct
{
unsigned long field1 : 8;
unsigned long field2 : 4;
unsigned long field3 : 1;
unsigned long field4 : 1;
unsigned long filed5 : 1;
unsigned long field6 : 1;
unsigned long field7 : 10;
unsigned long field8 : 10;
unsigned long field9 : 10;
unsigned long field10 : 10;
unsigned long field11 : 2;
unsigned long field12 : 2;
unsigned long field13 : 2;
unsigned long field14 : 2;
}t_bitfield_s;

typedef union
{
t_bitfield_s Struct;
unsigned char Array[8];
}t_bitfield_u;

pragma pack()


t_bitfield_u Test;


Data is not packed as expected. field1 up to field7 sum in total 26 bits. In the same unsigned long (32 bits) storage it would be possible to pack 6 additional bits from field 8. Due to the fact that the pragma is not considered, a new storage for unsigned long is started.

Expected Behavior:
Test.Array[0] = field1 (8 bits)
Test.Array[1] = field2 (4bits) field3 (1bit) field4 (1bit) field5 (1bit) field6 (1bit)
Test.Array[2] = field7 (8 bits)
Test.Array[3] = field7 (remaining 2 bits) field 8 (6 bits)
Test.Array[4] = field 8 (remaining 4 bits) field 9 (4 bits)
Test.Array[5] = field 9 (remaining 6 bits) field 10 (2 bits)
Test.Array[6] = field 10 (remaining 8 bits)
Test.Array[7] = field 11 (2bits) field 12 (2bits) field 13 (2bits) field 14 (2bits)




Actual Behavior:
Test.Array[0] = field1 (8 bits)
Test.Array[1] = field2 (4bits) field3 (1bit) field4 (1bit) field5 (1bit) field6 (1bit)
Test.Array[2] = field7 (8 bits)
Test.Array[3] = field7 (remaining 2 bits)
Test.Array[4] = field8 (8 bits)
Test.Array[5] = field8 (remaining 2 bits) field 9 (6 bits)
Test.Array[6] = field9 (remaining 4 bits) field 10 (4 bits)
Test.Array[7] = field 10 (remaining 6 bits) field 11 (2bits)
Test.Array[8] = field 12 (2bits) field 13 (2bits) field 14 (2bits)
Test.Array[9] = 0
Test.Array[10] = 0
Test.Array[11] = 0

What specifier/pragma can be used for MVS2015/2017/2019 to have the expected behaviour?
Thank you!

c++
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Viorel-1 avatar image
0 Votes"
Viorel-1 answered DarabanStefanRBROEES-5020 commented

Try 'unsigned long long' or 'unsigned __int64' instead of 'unsigned long'.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you @Viorel-1. This solution solves part of the problem. I have other examples in my code where this solution is not applicable. Let's say the truncation happens at 62 bits when another bit field which contains 10 bits has to be packed.

I am looking for a directive from MVS compiler that can replace #pragma pack(1).

0 Votes 0 ·
JeanineZhang-MSFT avatar image
0 Votes"
JeanineZhang-MSFT answered DarabanStefanRBROEES-5020 commented

Hi,

I am looking for a directive from MVS compiler that can replace #pragma pack(1).

I suggest you could try to use alignas specifier to control alignment.

For more details I suggest you could refer to the Doc: align (C++)

Best Regards,

Jeanine



If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@DarabanStefanRBROEES-5020

May I know if you have got any chance to check my answer? I am glad to help if you have any other questions.

0 Votes 0 ·

I used it and it does not work. This is the answer from Microsoft support team: "Neither #pragma pack, nor __declspec(align(1)) will add more bits to any C/C++ data type"

0 Votes 0 ·

Thank you @JeanineZhang-MSFT but it seems that the compiler does not support this and only a workaround has to be used specific to the particular case where the problem occurs.

0 Votes 0 ·