C++ boost::serialization中的派生类偏移量计算。它有效吗?

C++ boost::serialization中的派生类偏移量计算。它有效吗?,c++,boost,boost-serialization,C++,Boost,Boost Serialization,boost::序列化包含: 生成此输出 AddressSanitizer:DEADLYSIGNAL ================================================================= ==72613==ERROR: AddressSanitizer: SEGV on unknown address 0x0000000ffff8 (pc 0x0000004012d9 bp 0x7ffd5b3eecf0 sp 0x7ffd5b3eece0 T0) ==

boost::序列化
包含:

生成此输出

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)));
std::aligned_storage::type data;
重新解释强制转换(&U)数据
-重新解释(
静态浇铸(
重新解释(铸造和数据));
有人看到这个片段有什么问题吗?如果不是的话,我会把它推荐给
boost



更新日期:2019年12月16日:
boost::serialization
develope
分支的修复。

reinterpret\u cast(1如另一个答案所示,问题在于
(1刚刚检查,输出不同。此代码打印0,而
boost
版本打印-8。我认为问题出在
nullptr
中,这就是
boost
使用幻数的原因。“boost作者和编译器作者都同意这只是指针数学,因此无论如何它应该做正确的事情。”我对此不太确定。我一直看到这个假设,但它不一定成立。你不是在编写裸机程序——你是在抽象中编写的。虚拟继承就是这样一种情况:这样的代码肯定会被破坏。如果
派生的
实际上从
基继承而不是
最终的
,那么
STATICE-CASTEP<代码>将尝试读取该地址的对象,并失败地惊人地阅读。<代码> AligNeDySturial是C++ 11。Boost序列化至少需要C++版本吗?如果不是,我建议尝试另一种方法。UBSAN抱怨如果缓冲区没有对齐?好点,但是<代码> Boost 有自己的<代码> AlgndEdStoage
。我将使用它。
reinterpret_cast<Base *>(1 << 20)
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
std::aligned_storage<sizeof(Derived)>::type data;
reinterpret_cast<char*>(&data)
  - reinterpret_cast<char*>(
        static_cast<Base*>(
            reinterpret_cast<Derived*>(&data)));
reinterpret_cast<Base *>(1 << 20)
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>

class Foo { public: virtual void foo() {} };
class Base { public: virtual void base() {} };
class Derived: public Foo, public Base {};

int main() {
    alignas (Derived) char const buffer[sizeof(Derived)] = {};
    Derived const* const derived = reinterpret_cast<Derived const*>(buffer);
    Base const* const base = derived;
    ptrdiff_t const delta =
        reinterpret_cast<char const*>(derived) -
        reinterpret_cast<char const*>(base);
    ::printf("%td\n", delta);
    return 0;
}