I'm working on parsing network data stream, I'm wondering if there is any way I can map the data stream directly to the data structure.
For example, I want to define the data structure for an RTP protocol as follows.
class RTPHeader
{
int version:2; // The first two bits is version.
int P:1; // The next bits is an field P.
int X:1;
int CC:4;
int M:1;
int PT:7;
int sequenceNumber;
int64 timestamp;
.....
};
And using it this way.
RTPHeader header;
memcpy(&header, steamData, sizeof(header));
But as the C++ compiler will insert padding between the members, is there any way to control that so that no padding are added between members (including the bit field members)?
This question is NOT a duplicate of How to get rid of padding bytes between data members of a struct because there can be bit fields in my example.
In Structure, sometimes the size of the structure is more than the size of all structures members because of structure padding. Note: But what actual size of all structure member is 13 Bytes. So here total 3 bytes are wasted. So, to avoid structure padding we can use pragma pack as well as an attribute.
Structure Padding in C: The structure padding is automatically done by the compiler to make sure all its members are byte aligned. Here 'char' is only 1 byte but after 3 byte padding, the number starts at 4 byte boundary. For 'int' and 'double', it takes up 4 and 8 bytes respectively.
The structural padding is an in-built process that is automatically done by the compiler. Sometimes it required to avoid the structure padding in C as it makes the size of the structure greater than the size of the structure members.
structure AThe compiler will insert a padding byte after the char to ensure short int will have an address multiple of 2 (i.e. 2 byte aligned). The total size of structa_t will be sizeof(char) + 1 (padding) + sizeof(short), 1 + 1 + 2 = 4 bytes.
If you're able to use C++11, you can take advantage of the align control implemented with the alignof
operator.
If you cannot use a C++11 compiler, there's non-standard alternatives that can help you; in GCC the __attribute__(packed)
, and with MSVC the #pragma pack
.
If your choice is the GCC variant, the attribute must be placed at the end of the struct:
class RTPHeader
{
int version:2; // The first two bits is version.
int P:1; // The next bits is an field P.
int X:1;
int CC:4;
int M:1;
int PT:7;
int sequenceNumber;
int64 timestamp;
.....
} __attribute__((packed)) ; // attribute here!
If your choice is the MSVC one, the pragma must be placed before the struct:
#pragma pack(1) // pragma here!
class RTPHeader
{
int version:2; // The first two bits is version.
int P:1; // The next bits is an field P.
int X:1;
int CC:4;
int M:1;
int PT:7;
int sequenceNumber;
int64 timestamp;
.....
};
If your code must be compiled in both, the only way (without C++11 alignof
operator) is the conditional compilation:
#ifdef MSVC
#pragma pack(1)
#endif
class RTPHeader
{
int version:2; // The first two bits is version.
int P:1; // The next bits is an field P.
int X:1;
int CC:4;
int M:1;
int PT:7;
int sequenceNumber;
int64 timestamp;
.....
#ifdef GCC
}__attribute__((packed));
#else
};
#endif
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With