#include <iostream> struct S1 { char a; int b; char d; }; #pragma pack(1) struct S2 { char a; int b; char d; }; int main() { std::cout<<sizeof(S1)<<std::endl; std::cout<<sizeof(S2)<<std::endl; } 

output:

12

6

When should I use 1 byte alignment only with small amounts of memory? What are the pros and cons?

  • When it is necessary for compatibility - with other programs, API, etc. - Harry

2 answers 2

Go through the pros and cons.

  • pros
    • structures are smaller, less memory consumption
    • it is convenient when serializing / deserializing
    • sometimes it simplifies low-level code.
  • minuses
    • internal fields can be aligned "inconvenient" for the processor and you can get a slowdown of the program
    • sometimes the alignment may not be the same as the programmer expects. It can be different on different platforms or compiler versions. Therefore, sometimes it may not be suitable for serialization. It is necessary at least to strictly control through sizeof and other methods.
    • alignment works very specifically if there are bit fields (specifically, not as much as the programmer expects).

In general, alignment should be used in the following situations:

  • you need to store many, many structures and the speed of the program can be sacrificed. But maybe you can just reorder the fields.
  • a simple ipc is written and size matters (although it is better to take something ready)
  • The api of the operating system is used and "so needed."
  • I want to experiment and learn the compiler deeper.

PS By the way, there is a problem in the code. After applying the packaging, you need to carefully return it back. Yes, in this example, nothing will happen, but if the pragma pack gets into the header file, there may be a big problem - the same structure will have a different size in different compilation units, the fields will be aligned differently.

 #pragma pack(push, 1) struct Foo { // ... }; #pragma pack(pop) 

PSS You can read more on Habré .

    When to use? Then, when you know exactly what you are doing and it is absolutely necessary. What are the cons? Undefined behavior. Here is your modified code:

     #include <iostream> using std::cout; struct S1 { char a; int b; char d; }; #pragma pack(1) struct S2 { char a; int b; char d; }; int main() { cout << sizeof(S1) << "\n"; cout << sizeof(S2) << "\n"; cout << alignof(int) << "\n"; S2 s2; size_t address = reinterpret_cast<size_t>(&s2.b); cout << "Var address: " << std::hex << address << "\n"; cout << "Properly aligned? " << std::boolalpha << (address % alignof(int) == 0); } 

    The last line is likely to print false , which means that a variable of type int is located at an address that contradicts the alignment requirement for this type (standard [basic.align] ). And since this contradicts the requirements of the standard, then your program is incorrect.