Подтвердить что ты не робот

То, что предупреждение "выравнивание элемента чувствительно к упаковке" означает в С++

Что означает "выравнивание элемента в чувствительности к упаковке" в С++? Я использую Visual Studio 2005.

Как мне удалить эти предупреждения? Я не хочу их отключать.

4b9b3361

Ответ 1

Некоторые типы данных должны быть выровнены с определенной границей. Так, например:

struct V
{
  char a;
  double b;
  char c;
  double d;
};

sizeof (char) равен 1, а sizeof (double) равно 8, но размер этой структуры может быть больше, чем ожидаемый 18, если ему нужно удвоить, чтобы выровнять по 8-байтовой границе. В этом случае и потому, что члены должны появляться в памяти в том порядке, в котором они объявлены в структуре, может быть 7 байтов "заполнения", близких к члену c, и, возможно, некоторых с элементом a.

Опасность здесь возникает, когда упаковка нестандартная, поэтому размер этой структуры может меняться, и вы отправляете ее в "двоичном" формате по проводу или храните ее в файле, где он будет читаться в другом месте (даже если конечная точка двойника одинакова).

В качестве альтернативы предложениям по устранению предупреждения через прагмы вы можете решить использовать его в коде, изменив порядок своих членов. Поместите те, которые нуждаются в наибольшем выравнивании сначала, а нижние - позже. Итак, сначала наведите указатели и двойники, затем введите ints, затем shorts и любые члены char.

Ответ 2

Взято из MSDN -

'symbol': выравнивание элемента чувствительно к упаковке

Элемент структуры выравнивается по смещению памяти, значение которого не кратно размеру элемента. Например, следующий фрагмент кода выдаст это предупреждение:

// C4121.cpp
// compile with: /W4 /c
#pragma pack(2) // C4121
struct s
{
   char a;
   int b;
};

Чтобы предотвратить это предупреждение, вы можете внести одно из следующих изменений:

  • Измените pack(2) на pack(4).
  • Отмените порядок элементов структуры таким образом, чтобы int предшествовал char.

Когда данные не выровнены по границам, кратным размеру данных, производительность может ухудшиться, и если вы портируете код на машину RISC, он не будет компилироваться.

Вы можете указать выравнивание структуры С#pragma pack или /Zp. Обратите внимание, что компилятор не генерирует это предупреждение при указании/Zp1.