These structs, align1
and align2
, contain the same data, but align1
has more padding due to the nested layout.
How can I get the memory saving alignment of align2
while also using a nested struct like in align1
?
int main() {
struct align1 {
struct {
double d; // 8 bytes
bool b1; //+1 byte (+ 7 bytes padding) = 16 bytes
} subStruct;
bool b2; //+1 byte (+ 7 bytes padding) = 24 bytes
};
struct align2 {
double d; // 8 bytes
bool b1, b2; //+2 byte (+ 6 bytes padding) = 16 bytes
};
std::cout << "align1: " << sizeof(align1) << " bytes\n"; // 24 bytes
std::cout << "align2: " << sizeof(align2) << " bytes\n"; // 16 bytes
return 0;
}
The nested subStruct
struct is needed since it is going to be declared/defined outside. I'm using C++17 and Visual Studio 2017.
The resulting code can be as dirty or bad looking as hell. I just don't want it to throw random errors at me later on or break when changing the configuration.
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.
Rearranging members to reduce paddingYou can reduce the size of each widget by rearranging the members to reduce the number of padding bytes.
The total number of padding bytes is at least one, and is the number that is required in order to bring the data length up to a multiple of the cipher algorithm block size.
The variable 'c' is of 4 bytes, so it can be accessed in one cycle also, but in this scenario, it is utilizing 2 cycles. This is an unnecessary wastage of CPU cycles. Due to this reason, the structure padding concept was introduced to save the number of CPU cycles.
I explicitly rely on the permission to propose code which is "dirty or bad looking as" ... anything. To be even more clear, I only provide an idea. You need to test yourself and take responsibility yourself. I consider this question to explicitly allow untested code.
With this code:
typedef union
{
struct
{
double d; // 8 bytes
bool b1; //+1 byte (+ 7 bytes padding) = 16 bytes
} nested;
struct
{
double d; // 8 bytes
bool b1, b2; //+2 byte (+ 6 bytes padding) = 16 bytes
} packed;
} t_both;
I would expect the following attributes/features:
XXX.nested.d
and XXX.nested.b1
XXX.packed
XXX.packed.b2
to what is considered padding within nested
Whatever you do with this, it probably conflicts with the requirement that when writing and reading a union, then all read accesses must be to the same part of the union as the most recent write. Writing one and reading the other would hence not be strictly allowed. That is what I consider unclearn about this code proposal. That said, I have often used this kind of unions in environments for which the respective construct has explicity been tested.
In order to illustrate here is a functionally identical and also equally unclean version, which better illustrates that the substruct can be typdefed elsewhere:
/* Inside an included header "whatever.h" : */
typedef struct
{
double d; // 8 bytes
bool b1; //+1 byte (+ 7 bytes padding) = 16 bytes
} t_ExternDefedStruct;
/* Content of including file */
#include "whatever.h"
typedef union
{
t_ExternDefedStruct nested;
struct
{
double d; // 8 bytes
bool b1, b2; //+2 byte (+ 6 bytes padding) = 16 bytes
} packed;
} t_both;
With #pragma pack(push, 1)
and some manual padding, you can get them to be the same.
#include <iostream>
int main() {
#pragma pack(push, 1)
struct align1 {
struct {
double d; // 8 bytes
bool b1; //+1 byte (+ 0 bytes padding) = 9 bytes
} subStruct;
bool b2; //+1 byte (+ 0 bytes padding) = 10 bytes
char pad_[6]; //+6 bytes (+ 0 bytes padding) = 16 bytes
};
#pragma pack(pop)
struct align2 {
double d; // 8 bytes
bool b1, b2; //+2 byte (+ 6 bytes padding) = 16 bytes
};
std::cout << "align1: " << sizeof(align1) << " bytes\n"; // 16 bytes
std::cout << "align2: " << sizeof(align2) << " bytes\n"; // 16 bytes
return 0;
}
Output:
align1: 16 bytes align2: 16 bytes
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