Что означает предупреждение "padding class" Tester с 4 байтами?
Для этого упрощенного тестового примера:
#include <map>
class Tester {
int foo;
std::map<int, int> smap;
};
int main() {
Tester test;
return 0;
}
Я получаю следующее предупреждение компилятора:
$ clang++ -std=c++98 -Weverything test.cc
test.cc:5:24: warning: padding class 'Tester' with 4 bytes to align 'smap' [-Wpadded]
std::map<int, int> smap;
^
Может ли кто-нибудь объяснить, что означает это предупреждение, и как я должен его решить?
Ответы
Ответ 1
Здесь нет настоящей проблемы. В C и С++ компилятору разрешено вставлять дополнения после элементов структуры, чтобы обеспечить лучшее выравнивание и, таким образом, обеспечить более быстрый доступ к памяти. В этом случае, похоже, решил поместить smap
на 8-байтовое выравнивание. Поскольку int
почти наверняка четыре байта, предупреждение сообщает вам, что в середине структуры есть четыре байта потраченного пространства.
Если бы было больше членов структуры, то одна вещь, которую вы могли бы попробовать, заключалась бы в том, чтобы переключить порядок определений. Например, если у вашего Tester
были члены:
struct Tester {
int foo;
std::map<int, int> smap;
int bar;
};
тогда было бы целесообразно разместить два интервала рядом друг с другом, чтобы оптимизировать выравнивание и избежать потраченного впустую пространства. Однако в этом случае у вас есть только два члена, и если вы переключите их, то компилятор, вероятно, добавит четыре байта заполнения в конец структуры, чтобы оптимизировать выравнивание Tester
при размещении внутри массива,
Ответ 2
Я предполагаю, что вы компилируете это в 64-разрядной системе.
В 64-битных системах указатели составляют 8 байтов. Компиляторы будут выровнять элементы структуры с естественными границами, поэтому 8-байтовый указатель начнет со смещения в структуре, кратном 8 байтам.
Поскольку int
всего четыре байта, компилятор вставил 4 байта "заполнения" после foo
, так что smap
находится на 8-байтовой границе.
Изменить: хотя smap
не является указателем, а <<24 > , применяется такая же логика. Я не уверен, какие точные правила для выравнивания объектов, но то же самое происходит.
Что делать? Ничего. Ваш код отлично работает, компилятор просто сообщает вам, что это произошло. Там абсолютно не о чем беспокоиться. -Weverything
означает включение всех возможных предупреждений, что, вероятно, является чрезмерным для большинства компиляций.