Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与基类不同的子类对齐要求_C++_Inheritance_C++17_Memory Alignment - Fatal编程技术网

C++ 与基类不同的子类对齐要求

C++ 与基类不同的子类对齐要求,c++,inheritance,c++17,memory-alignment,C++,Inheritance,C++17,Memory Alignment,我使用的是一个非常简单的结构,它只包含几个双字节 让我们称之为: struct A { double x; double y; double z; virtual ~A() = default; }; 在我的计算机上,使用clang++10.0.1,此结构的对齐要求为8字节(alignof(A)==8) 此结构由第二个结构继承: struct B : public A { Eigen::Quaternion<double> quat; };

我使用的是一个非常简单的结构,它只包含几个双字节

让我们称之为:

struct A {
    double x;
    double y;
    double z;

    virtual ~A() = default;
};
在我的计算机上,使用clang++10.0.1,此结构的对齐要求为8字节(
alignof(A)==8

此结构由第二个结构继承:

struct B : public A {
    Eigen::Quaternion<double> quat;
};
所以,这看起来像是一个对齐问题。它期望A对齐32字节,而实际对齐8字节(“类型“A”的未对齐地址xxx内的成员访问,需要32字节对齐”)。如果我强制
A
到32字节对齐(使用
alignas(32)
),一切都会正常,但我不确定是解决了问题还是只是症状

我不明白为什么使用对A
B
的引用访问
A::x
需要通过vptr(成员变量应该是本地的?)。我不明白为什么从B引用访问A的成员变量时,B的对齐要求会应用于A。我一开始真的不明白这个问题

我的修复(手动对齐基本结构)是否足以修复问题,还是存在更大的潜在问题?有没有什么资源可以讨论这个问题?(成员变量和继承的对齐要求)

这是很多问题。对不起



编辑1:我刚刚注意到,声明函数的.cpp文件与调用它的文件位于不同的库中。这可能是链接器的问题吗?或者在两个库上编译不同的东西(尽管我的项目的所有内部库共享相同的编译器选项)。

请在问题中包括一个问题:您真的使用
-std=c++17
编译吗?可能有关联。另外,.@idclev463035818我无法在代码之外复制它,我尝试了很多东西,它总是有效的。所以我的问题不是“修复我的代码”的问题,而是“修复我对这个应该如何工作的理解”的问题,我认为这不需要一个最小的可复制的例子。@DanielLangr是的,我确信代码是用C++17编译的,因为我在同一版本中大量使用了其他C++17特性file@Ebatsin如果您不能在代码之外重现问题,那么问题可能在代码的其他地方。至于调试,您会说如果在函数调用之前放置一个断点,那么向量就非常好了。一旦你进入这个功能,它就坏了?这听起来真的很奇怪,除了通过引用传递参数外,中间没有执行任何操作。
std::vector<B> vec;
// doing stuff with vec, filling it with data
// vec and its content are perfectly valid here
doStuff(vec);
void doStuff(std::vector<B>& inOut) {
    for(const B& p: inOut) {
        // I try to access an element of B, I get a segfault here
        auto copy = p.x;
    }
}
stl_iterator.h:969:16: runtime error: reference binding to misaligned address 0x7fb0eace6010 for type 'B', which requires 32 byte alignment
0x7fb0eace6010: note: pointer points here
 00 00 00 00  b8 31 76 a9 b1 7f 00 00  b0 72 33 94 a4 9c 49 42  00 00 8f 88 b4 33 51 40  00 10 e2 8e
              ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior stl_iterator.h:969:16 in 
doStuff.cpp:2: runtime error: reference binding to misaligned address 0x7fb0eace6010 for type 'const B', which requires 32 byte alignment
0x7fb0eace6010: note: pointer points here
 00 00 00 00  b8 31 76 a9 b1 7f 00 00  b0 72 33 94 a4 9c 49 42  00 00 8f 88 b4 33 51 40  00 10 e2 8e
              ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior doStuff.cpp:2 in 
doStuff.cpp:3: runtime error: upcast of misaligned address 0x7fb0eace6010 for type 'B', which requires 32 byte alignment
0x7fb0eace6010: note: pointer points here
 00 00 00 00  b8 31 76 a9 b1 7f 00 00  b0 72 33 94 a4 9c 49 42  00 00 8f 88 b4 33 51 40  00 10 e2 8e
              ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior doStuff.cpp:3: in 
doStuff.cpp:3: runtime error: member access within misaligned address 0x7fb0eace6010 for type 'A', which requires 32 byte alignment
0x7fb0eace6010: note: pointer points here
 00 00 00 00  b8 31 76 a9 b1 7f 00 00  b0 72 33 94 a4 9c 49 42  00 00 8f 88 b4 33 51 40  00 10 e2 8e

==33989==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x0000000000a4 (pc 0x7fb1a8d187bf bp 0x7fb1a9763158 sp 0x7fb1727ec240 T34466)
==33989==The signal is caused by a READ memory access.
==33989==Hint: address points to the zero page.
    #0 0x7fb1a8d187bf in __dynamic_cast /build/gcc/src/gcc/libstdc++-v3/libsupc++/dyncast.cc:50:15
    #1 0x55a9ee96a6a5 in __ubsan::checkDynamicType(void*, void*, unsigned long)
    #2 0x55a9ee9695c3 in HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions)
    #3 0x55a9ee969c70 in __ubsan_handle_dynamic_type_cache_miss
    #4 0x7fb1ac1c75d8 in doStuff(std::vector<B, std::allocator<B> >&) doStuff.cpp:29:35