gpt4 book ai didi

c++ - 使用 std::launder 从指向非事件对象的指针获取指向事件对象成员的指针?

转载 作者:可可西里 更新时间:2023-11-01 16:18:40 26 4
gpt4 key购买 nike

这个问题跟在这个 one 之后

让我们考虑这个示例代码:

struct sso
{
union{
struct {
char* ptr;
char size_r[8];
} large_str;
char short_str[16];
};

bool is_short_str() const{
return *std::launder(short_str+15)=='\0'; //UB?
}
};

如果 short_str 不是事件成员,则在没有 std::launder 的情况下取消引用指针将是 UB。让我们考虑一下 ABI 已明确指定,并且我们知道 size_r[7] 与 short_str[15] 位于同一地址。当 short_str 不是 union 体的活跃成员时,std::launder(short_str+15) 是否返回指向 size_r[7] 的指针?


注意:我认为是这样,因为[ptr.launder]/3

A byte of storage is reachable through a pointer value that points to an object Y if it is within the storage occupied by Y, an object that is pointer-interconvertible with Y, or the immediately-enclosing array object if Y is an array element.

最佳答案

Let's consider that the ABI is well specified and that we know that size_r[7] is at the same address as short_str[15]

这完全取决于保证的确切含义。

编译器可以自由保证

Sso.short_str[15]

即使 Sso.large_str 当前处于事件状态,也可以访问和修改所有内容,并获得您期望的语义。

或者不提供该保证是自由的。

对于格式错误或表现出未定义行为的行为或程序没有限制。

由于那里没有对象,&Sso.short_str[15] 不能与任何对象进行指针互换。不存在的对象不具有与另一个对象“相同的地址”。

Launder 是根据指向预先存在的对象的指针来定义的。然后销毁该指针,并创建一个具有相同地址的新对象(定义明确)。 std::launder 然后让您获取指向不再存在的对象的指针,并获得指向现有对象的指针。

你所做的不是那个。如果您在 参与时获取了 &short_str[15],您就会有一个指向对象的指针。 ABI 可以说这与 size_r[7] 位于同一地址。现在 std::launder 将处于有效性范围内。

但编译器可以更进一步,定义 short_str[15] 引用与 size_r[7] 相同的对象,即使它不是事件的.

只有在 short_str[15] 处于事件状态时获取地址时,我才能看到与您的内容保持一致的最弱 ABI 保证才有效;稍后,您将使用 large_str,然后您可以从 &short_str[15] 洗钱到 &size_r[7]。与您的声明一致的最强 ABI 保证不需要调用 std::launder。中间的某个地方需要 std::launder

关于c++ - 使用 std::launder 从指向非事件对象的指针获取指向事件对象成员的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48189026/

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