Страницы

Поиск по вопросам

понедельник, 16 декабря 2019 г.

Можно ли автоматизировать padding в конце структуры?

#cpp #макрос


В компиляторе есть флаг -Wpadded, который выдает предупреждения, если компилятор
вынужден в целях выравнивания добавлять память к объявленным в структуре полям.


  Warn if padding is included in a structure, either to align an element
  of the
             structure or to align the whole structure.  Sometimes when this happens
it is possible
             to rearrange the fields of the structure to reduce the padding and so
make the
             structure smaller.


Вопрос: Можно ли сделать макрос (не требующий ручного подсчета байт) для добавления
поля, хотя бы  в конец структуры, с целью подавления этих сообщений?

Например, хотелось бы писать что-то в таком духе:

struct x {
  int a;
  char c;
  TAILPAD;
};


В данном случае макрос TAILPAD  должен расширяться в текст

char _padding_[3]


Вариант с разумным числом аргументов макроса (а также любое другое решение, не требующее
чрезмерного ввода символов (а тем более написания скриптов, редактирующих исходник))
также вполне подойдет.
    


Ответы

Ответ 1



Интересно не упаковать поля, а дополнить структуру до подходящего для выравнивания размера. Компилятор обычно это и делает, просто -Wpadded заставляет его об этом предупреждать, дабы программист сам разбирался со своими выравниваниями. Писать подобные макросы — это фактически выполнять работу компилятора за него. Дабы не изобретать велосипед можно явно отключить это предупреждение для отдельных структур: #define AUTO_PADDING_START \ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wpadded\"") #define AUTO_PADDING_END \ _Pragma("GCC diagnostic pop") AUTO_PADDING_START; struct S { int a; char c[1]; }; AUTO_PADDING_END; Ответ тоже из серии обходных путей, но для задачи «не отключать предупреждение глобально, но выравнивать некоторые структуры автоматически», пожалуй, хватит...

Ответ 2



Чтобы погасить пердуперждение -Wpadded, достаточно в конец дописать прагму pack struct x { int a; char c; #pragma pack(1) }; Срабатывает как в C, так и в C++

Комментариев нет:

Отправить комментарий