Обычный способ обеспечить размер класса — добавить отступ соответствующего размера:

class C 
{    
    int foo;
    uint8_t padding[PADDINGSIZE];
};

Затем sizeof(C) можно также проверить с помощью static_assert.

Но это неудобно. Есть ли надежное решение для принудительного применения sizeof(C) к определенному значению с дополнением или без него, но без необходимости указывать PADDINGSIZE?

c++
1
ardabro 18 Янв 2022 в 19:08
1
Однако вам нужно больше, чтобы убедить компилятор. например #прагма пакет(1)
 – 
Pepijn Kramer
18 Янв 2022 в 19:18
4
Какое бы решение вы ни выбрали, я бы рекомендовал добавить static_assert, чтобы компилятор предупредил вас, если предполагаемое решение не работает должным образом.
 – 
François Andrieux
18 Янв 2022 в 19:36
1
Можете ли вы объяснить, что такое вариант использования?
 – 
Klaus
18 Янв 2022 в 19:42

3 ответа

Вероятно, лучшим вариантом будет использование union. Грубо говоря, без некоторых деталей:

class C 
{    
    int foo;
};

union CAlloc
{
    C instance;
    std::byte enforced_size[DESIRED_SIZE];
};

Затем используйте CAlloc::instance, где это необходимо.

Обновление: как указал @Mgetz в комментариях, std::byte является дополнением С++ 17, вам может понадобиться/нужно использовать char, если вы используете более старый стандарт.

2
Jon Reeves 18 Янв 2022 в 19:24
Это обеспечивает минимальный размер, а не определенный размер, как запросил OP. Тем не менее, даже несмотря на то, что OP не просил минимум, он все же может соответствовать истинной неустановленной цели OP.
 – 
chux - Reinstate Monica
18 Янв 2022 в 19:40

В C++11 появилось новое ключевое слово: alignas Я думаю, что это нечто большее. удобно с вашей точки зрения.

1
Marek R 18 Янв 2022 в 19:18

В общем я бы сказал, что невозможно обеспечить определенный размер класса.

Рассмотрим желаемый размер 13. int foo; uint8_t padding[13 - sizeof(int)]; не сделает класс размером 13, так как после .padding[] обязательно произойдет заполнение.

Желаемый PADDINGSIZE должен будет соответствовать условиям, зависящим от предыдущих членов в классе и минимальных требований к выравниванию класса. Конечно есть минимум, т.к. uint8_t padding[some_negative]; работать не будет.

Рассмотрим ниже, где PADDINGSIZE + 7 может быть кратным 8, чтобы избежать заполнения после .padding[].

class C2 {    
    int foo;
    double d;
    int uint8_t b[1];
    uint8_t padding[PADDINGSIZE];
}
0
chux - Reinstate Monica 18 Янв 2022 в 19:36