MSVC C ++ 17 - предупреждение C4121 «выравнивание элемента было чувствительным к упаковке» - PullRequest
0 голосов
/ 03 января 2019

Я пробовал код ниже на VS2017 (версия 15.9) и предварительный просмотр VS2019 - это ложный положительный результат?

class Base {};
class Derived1 : public virtual Base {}; // to avoid diamond pattern in real code
class Derived2 : public Base {}; 

struct S1 {
    int i;
    void(Derived1::*func)(); // warning C4121 - see below for full text
};

struct S2 {
    int i;
    void(Derived2::*func)();  // no warning
};

int main()
{

}

r:\cpp2019\cpp2019\cpp2019.cpp(9) : warning C4121 : 'S1' : alignment of a member was sensitive to packing

Я сделал код как можно более простым (очевидно, это не настоящий производственный код). В производственном коде (огромная кодовая база) предупреждение возникает из-за итерации по карте с использованием цикла for на основе диапазона. Переменная цикла , конечно, std::pair<keytype, valuetype>, тип значения похож на func в struct S1.

Рабочий код прекрасно скомпилирован в VS2015, но теперь, когда VS2017 и языковой стандарт установлены на C ++ 17, я получаю это предупреждение.

1 Ответ

0 голосов
/ 03 января 2019

Это из-за sizeof(S1::func)==sizeof(void*)*3, из-за поддержки виртуального наследования, и sizeof(S2::func)==sizeof(void*)*1

Вы можете контролировать реализацию указателя на член с помощью #pragma pointers_to_members. Например, с этим у вас будет предупреждение для обоих случаев.

#pragma pointers_to_members( full_generality, virtual_inheritance)

Поскольку упаковка по умолчанию - 8, предупреждение логично.

Тем не менее я думаю, что это ложный позитив. Хотя такой указатель может появиться на явно смещенной границе, он фактически реализован в виде трех указателей, поэтому каждый из них будет правильно выровнен.

...