首页 > 解决方案 > MSVC C++ 17 - 警告 C4121“成员的对齐对打包很敏感”

问题描述

我已经在 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>值类型类似于funcin struct S1

生产代码在 VS2015 中编译良好,但现在使用 VS2017 并将语言标准设置为 C++17,我收到此警告。

标签: c++visual-c++visual-studio-2017c++17

解决方案


这是因为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,警告是合乎逻辑的。

我仍然认为这是一个误报。虽然这样的指针会出现在明显未对齐的边界上,但它实际上是作为三个指针实现的,因此每个指针都会正确对齐。


推荐阅读