gpt4 book ai didi

c++ - 多个 CRTP 基类的对齐

转载 作者:行者123 更新时间:2023-12-03 10:04:26 27 4
gpt4 key购买 nike

在CRTP中,基础对象可以return a reference to the derived object via static cast .
在多重继承的情况下也是如此吗?第二个基址及以后的地址可能与派生对象不同。考虑例如:

#include <iostream>
#include <string_view>

template<typename Derived>
struct Base1
{
char c1;
};

template<typename Derived>
struct Base2
{
char c2;
auto& get2() const
{
return static_cast<const Derived&>(*this); // <-- OK?
}
};

struct X : public Base1<X>, public Base2<X>
{
X(std::string_view d) : data{d} {}

std::string_view data;
};


int main()
{
auto x = X{"cheesecake"};

std::cout << x.get2().data << std::endl;
}
gcc 的未定义行为分析器 says this is undefined behavior .
clang 的未定义行为分析器 detects no problem .
标准是否说明了他们中的哪一个是正确的?
更新:
gcc 中的错误现在已经在主干上修复了。

最佳答案

是的,这是定义的,您的代码没问题。多重继承是一种罕见的情况,其中强制转换的指针与原始指针不同。
如果你去源码:

[expr.static.cast.11] A prvalue of type “pointer to cv1 B”, where B is a class type, can beconverted to a prvalue of type “pointer to cv2 D”, where D is acomplete class derived from B, if cv2 is the same cv-qualification as,or greater cv-qualification than, cv1. ....


[expr.static.cast.2] An lvalue of type “cv1 B”, where B is a class type, can be cast to type “reference to cv2 D”, where D is a class derived from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. ...


这意味着您使用的强制转换是有效的,并且只要您不丢弃任何 cv 限定符,使用指针的情况也是如此。
据我所知,这是 sanitizer 中的一个错误,当它们必须被重定向时,它在转换引用时遇到了麻烦。
首先,这与 CRTP 无关。以下完全相同,CRTP 会自动为我们执行此操作。
Base2<X>* base = &x;
const X* orig = static_cast<const X*>(base);

std::cout << &x << std::endl;
std::cout << base << std::endl;
std::cout << orig << std::endl;
输出:
0x7ffc7eeab4d0
0x7ffc7eeab4d1
0x7ffc7eeab4d0
这是正确的,gcc 的 sanitizer 不会提示任何事情。
但是,如果您更改指向引用的指针:
X x{"cheesecake"};

Base2<X>& base = x;
const X& orig = static_cast<const X&>(base);//Line 36

std::cout << &x << std::endl;
std::cout << &base << std::endl;
std::cout << &orig << std::endl;
突然你得到
0x7ffdbf87cf50
0x7ffdbf87cf51
0x7ffdbf87cf50

Program stderr

example.cpp:36:14: runtime error: reference binding to misaligned address 0x7ffdbf87cf51 for type 'const struct X', which requires 8 byte alignment
0x7ffdbf87cf51: note: pointer points here
00 00 00 60 cf 87 bf fd 7f 00 00 0a 00 00 00 00 00 00 00 66 20 40 00 00 00 00 00 6d 19 40 00 00
^
这意味着输出再次正确,但 sanitizer 在回滚时不正确地重定向引用。

关于c++ - 多个 CRTP 基类的对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65177399/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com