Выравнивание структур вручную

282
29 сентября 2017, 18:52

Допустим вам требуется вручную выровнять все поля структуры по 4 байта. Выглядит это примерно так:

#pragma pack(push,1) //Или что-то аналогичное
//...
struct S{
    uint8_t a;
    uint8_t pad1;   //Выравнивание
    uint16_t pad2;  //Выравнивание
    uint32_t b;
};

Теперь вопрос. Какие еще есть способы добиться того-же результата? Атрибуты компилятора, какие-нибудь новые возможности языка(С++11, 14, 17, 20), трюки с битовыми полями?

Answer 1

В стандарте С++ есть в разделе 3.11 alignof и в 7.6.2 - alignas, т.е. вроде бы можно указать что-то типа struct alignas(8) S { ... };, но (чисто мое мнение) описано оно не очень внятно, что лично я по привычке использую средства компилятора.

В Visual C++, например, это (помимо ключика /Zp) #pragma pack, обеспечивающая тонкую настройку выравнивания - вплоть до отдельных структур.

Вот такой код в VC++ 2015

#include <iostream>
#include <iomanip>
using namespace std;
struct alignas(16) S16
{
    char a;
    int  b;
    char c;
    int  d;
};
struct alignas(4) S4
{
    char a;
    int  b;
    char c;
    int  d;
};

#pragma pack(push,1)
struct S1
{
    char a;
    int  b;
    char c;
    int  d;
};
#pragma pack(pop)
#pragma pack(push,2)
struct S2
{
    char a;
    int  b;
    char c;
    int  d;
};
#pragma pack(pop)

int main(int argc, const char * argv[])
{
    cout << "sizeof(S16) = " << sizeof(S16) << endl;
    cout << "sizeof(S4)  = " << sizeof(S4) << endl;
    cout << "sizeof(S2)  = " << sizeof(S2) << endl;
    cout << "sizeof(S1)  = " << sizeof(S1) << endl;
}

дает

sizeof(S16) = 16
sizeof(S4)  = 16
sizeof(S2)  = 12
sizeof(S1)  = 10
Answer 2

Один из вариантов это использовать свойства битовых полей:

struct S{
    uint8_t a;
    uint32_t :0;  //Выравнивание до границы 32-битного поля
    uint32_t b;
};

Неименованное битовое поле нулевой длинны заставляет компилятор "сделать отступ" до границы поля заданного типа.

The special unnamed bit field of size zero can be forced to break up padding. It specifies that the next bit field begins at the beginning of its allocation unit.

Я, правда, немного сомневаюсь в переносимости этого решения. Но, вроде, работает

READ ALSO
Выборка jq и Angular

Выборка jq и Angular

У меня есть таблица, данные там формируются с помощью ng-repeat

282
Выпадает символ при чтении параметра JSON

Выпадает символ при чтении параметра JSON

Есть такой вот участок кода, который читае полученные AJAX данный в JSON формате(лишний код убран):

289
Тень по центру, css, полукруглая тень

Тень по центру, css, полукруглая тень

Как сделать такую тень как на рисунке? те

353