Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::pair<U,V> alignment control

I noticed one unpleasant thing that happens with std::pair when tried to save it into binary file: std::pair is aligned to a word. It might be useful in terms of processor efficiency, but requires more storage space, so I want to switch align mode to 1-byte for std::pair. My compiler is MS VC++ 2012.

#include <iostream>

int main( )
{
    struct S_a { double a; size_t b; };

#pragma pack(1)
    struct S_wa { double a; size_t b; };

    std::cout << sizeof( size_t ) << '\n';                          // 4
    std::cout << sizeof( double ) << '\n';                          // 8
    std::cout << sizeof( std::pair< size_t, size_t > ) << '\n';     // 8
    std::cout << sizeof( std::pair< double, size_t > ) << '\n';     // 16 - bad
    std::cout << sizeof( S_wa ) << '\n';                            // 12 - good
    std::cout << sizeof( S_a ) << '\n';                             // 16
    std::cout << sizeof( std::pair< double, double > ) << '\n';     // 16
}

I tried this, but it doesn't work:

#pragma pack(1)
    typedef std::pair< double, size_t > Q;

    std::cout << sizeof( Q ) << '\n';                               // 16
like image 590
Alexander Mihailov Avatar asked Aug 16 '13 03:08

Alexander Mihailov


1 Answers

A std::pair basically reduces down to:

class xxx
{
   T1 _t1;
   T2 _t2;
};

The alignment of the two members is defined by the alignment in force when the template itself is defined, not just when it's used to instantiate an instance.

The Microsoft implementation of the STL uses the symbol _CRT_PACKING to define the packing used for all STL components. By default the packing is set to 8. If you define this symbol yourself before including the header that defines std::pair (<utility>) you can theoretically override the packing and set your own.

Be aware of potential problems you may encounter calling libraries or other code that assumes the standard packing.

like image 66
Jonathan Potter Avatar answered Oct 06 '22 16:10

Jonathan Potter