MSVC C++ 17 - warning C4121 "alignment of a member was sensitive to packing"

Viewed 374

I have tried the code below on VS2017 (version 15.9) and VS2019 preview - is this a false positive?

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

I have made the code as simple as possible (it's not the actual production code obviously). In the production code (a huge codebase), the warning is due to iterating over a map using a range-based for loop. The loop variable is of course, std::pair<keytype, valuetype>, the value type is similar to func in struct S1.

The production code compiled fine in VS2015, but now with VS2017 and the language standard set to C++17, I get this warning.

1 Answers

It is because of sizeof(S1::func)==sizeof(void*)*3, due to support of virtual inheritance, and sizeof(S2::func)==sizeof(void*)*1

You can control implementation of pointer-to-member by #pragma pointers_to_members. For example with this you'll have warning for both cases.

#pragma pointers_to_members( full_generality, virtual_inheritance)

As default packing is 8, warning is logical.

Still I think it is a false positive. Although such pointer would appear on apparently misaligned boundary, it is actually implemented as three pointers, so each would be properly aligned.

Related