c++ - boost::serialization 中的派生类偏移计算。它有效吗?
问题描述
boost::serialization
包含此代码:
reinterpret_cast<std::ptrdiff_t>(
static_cast<Derived *>(
reinterpret_cast<Base *>(1 << 20)
)
) - (1 << 20)
其目的是计算基类和派生类之间的偏移量。这段代码是否没有未定义的行为?
我问的原因是 ASAN+UBSAN 抱怨。例如,这段代码
#include <iostream>
class Foo { public: virtual void foo() {} };
class Base { public: virtual void base() {} };
class Derived: public Foo, public Base {};
int main()
{
std::cout <<
(reinterpret_cast<std::ptrdiff_t>(
static_cast<Derived *>(
reinterpret_cast<Base *>(1 << 20)
)
) - (1 << 20));
}
编译为(gcc 版本 9.2.1)
g++ -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -g main.cpp
产生这个输出
AddressSanitizer:DEADLYSIGNAL
=================================================================
==72613==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000ffff8 (pc 0x0000004012d9 bp 0x7ffd5b3eecf0 sp 0x7ffd5b3eece0 T0)
==72613==The signal is caused by a READ memory access.
#0 0x4012d8 in main main.cpp:13
#1 0x7f74a90d5f42 in __libc_start_main (/lib64/libc.so.6+0x23f42)
#2 0x40112d in _start (/home/.../a.out+0x40112d)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV main.cpp:13 in main
是误报还是这段代码真的有问题?
2019 年 12 月 9 日更新:根据 Filipp 的建议和我的实验,这段代码似乎可以工作并且不会产生任何警告:
std::aligned_storage<sizeof(Derived)>::type data;
reinterpret_cast<char*>(&data)
- reinterpret_cast<char*>(
static_cast<Base*>(
reinterpret_cast<Derived*>(&data)));
有人看到这个片段有什么问题吗?如果没有,我会建议它boost
。
16.12.2019 更新:修复已合并到boost::serialization
develop
分支。
解决方案
reinterpret_cast<Base *>(1 << 20)
这不是一个有效的指针。
static_cast
需要评估它,它具有未定义的行为。
这是一个有趣的“技巧”,但似乎没有明确定义,-fsanitize
选项的结果证实了这一点。
推荐阅读
- python - 在 Pandas 中表示树视图方案的 excel 文件的数据框转换
- python - 如何使用 logger 在 Python 中仅用一行打印一个列表
- sql - SQL server 获取存储过程中使用的表列表,包括链接表(来自不同数据库的表)
- javascript - 使用 jQuery 在 Leaflet 弹出窗口中动态创建的内容
- javascript - 使用扩展运算符向对象添加属性
- python - conda install -c conda-forge python-pdal 求解环境:| 运行 Windows 10 时挂起
- java - 在服务器中从 gcm 迁移到 fcm
- json - 多嵌套 Json 导入到谷歌表格,没有逻辑排序并给出范围错误
- laravel - 无法从 Laravel 应用程序发送电子邮件:无法与主机 smtp.gmail.com 建立连接 [连接超时 #110]
- swift - 在 iOS 11.4 中使用 MKSlidingTableViewCell 为单元格动画创建多个单元格对象时崩溃