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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With