c++ - 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>
值类型类似于func
in struct S1
。
生产代码在 VS2015 中编译良好,但现在使用 VS2017 并将语言标准设置为 C++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,警告是合乎逻辑的。
我仍然认为这是一个误报。虽然这样的指针会出现在明显未对齐的边界上,但它实际上是作为三个指针实现的,因此每个指针都会正确对齐。
推荐阅读
- javascript - 根据 PHP 返回更改内部 HTML
- css - 类大于 n 的 CSS 目标项,与其他类无关
- python - 删除mysql查询python结果的行但不从数据库中删除
- ios - Swift NumberFormat 返回 0.00
- swift - 如何快速设置滑块初始值?
- c# - 如何填充
- json - 将 JSON 直接传递到 SQL Server 2016
- graph - PowerBI - 该日期的列总和高于 0.5 的天数
- dynamics-crm - 如何在 Dynamics 365 中将活动(邮件、笔记等)从一个联系人转移到另一个联系人
- node.js - 致命错误:CALL_AND_RETRY_LAST 分配失败 - JavaScript 堆内存不足 - NodeJS