gpt4 book ai didi

c++ - 我可以确保 RVO 用于重新解释的值吗?

转载 作者:行者123 更新时间:2023-11-30 02:21:38 26 4
gpt4 key购买 nike

假设我写了:

Foo get_a_foo() {
return reinterpret_cast<Foo>(get_a_bar());
}

并假设 sizeof(Foo) == sizeof(Bar)

当我使用 reinterpret_cast 来“打破规则”时,返回值优化是否一定要在这里进行,或者是否允许编译器为所欲为?如果我没有获得 RVO,或者无法保证获得 RVO - 我可以更改此代码以确保它发生吗?

我的问题是关于 C++11 和 C++17(如果我没记错的话,因为它有一些变化 w.r.t. RVO)。

最佳答案

Suppose I've written:

Foo get_a_foo() {
return reinterpret_cast<Foo>(get_a_bar());
}

and suppose that sizeof(Foo) == sizeof(Bar).

reinterpret_cast 对所有可能的 FooBar 类型都不合法。它仅适用于以下情况:

  1. Bar 是一个指针,Foo 是一个指针或一个足以容纳指针的整数/枚举。
  2. Bar 是一个足以容纳指针的整数/枚举,Foo 是一个指针。
  3. Bar 是对象类型,Foo 是引用类型。

还有一些我没有涉及的其他情况,但它们要么无关紧要(nullptr_t 转换),要么属于 #1 或 #2 的类似问题。

看,在处理基本类型时,省略实际上并不重要。您无法分辨省略基本类型的复制/移动与不省略它之间的区别。那么那里有转换吗?编译器只是使用返回值寄存器吗?这取决于编译器,通过“好像”规则。

并且在返回引用类型时省略不适用,因此 #3 不适用。

但如果 FooBar 是用户定义的对象类型(或指针、整数或成员指针以外的对象类型),则转换为 is ill-formed . reinterpret_cast 不是某种普通的 memcpy 转换函数。

所以让我们用一些您知道的可以实际工作的代码替换它:

Foo get_a_foo()
{
return std::bit_cast<Foo>(get_a_bar());
}

在哪里C++20's std::bit_cast有效地将一种普通可复制类型转换为另一种普通可复制类型。

该转换仍然不会被忽略。或者至少,不是通常使用“省略”的方式。

因为这两种类型是平凡可复制的,而bit_cast只会调用平凡的构造函数,编译器当然可以删除构造函数,甚至使用get_a_foo的返回值对象作为 get_a_bar 的返回值对象。因此,它可以被视为“省略”。

但“省略”通常指的是标准中允许实现忽略甚至非平凡的构造函数/析构函数的部分。编译器只能执行上述操作,因为所有构造函数和析构函数都是微不足道的。如果它们是非平凡的,则它们不能被忽略(话又说回来,如果它们是非平凡的,std::bit_cast 将不起作用)。

我的观点是,上述转换的优化不是由于“省略”或 RVO 规则;这完全是由于“好像”规则。即使在 C++17 中,bit_cast 调用是否有效地成为 noop 完全取决于编译器。是的,在创建 Foo 纯右值后,C++17 要求将其“省略”复制到函数的返回值对象中。

但是转换本身不是省略的问题。

关于c++ - 我可以确保 RVO 用于重新解释的值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48117322/

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