gpt4 book ai didi

c++ - Clang 修改析构函数中的返回值?

转载 作者:可可西里 更新时间:2023-11-01 16:39:45 25 4
gpt4 key购买 nike

在尝试编写一个类来计时调用它的构造函数和析构函数之间的持续时间时,我遇到了我认为是 clang 中的错误。 (编辑:这不是错误;它是实现定义的复制省略)

下面的 timer 结构保留指向作为引用传入的持续时间对象的指针,并将范围的持续时间添加到此。

#include <iostream>
#include <chrono>
struct timer {
using clock = std::chrono::high_resolution_clock;
using time_point = clock::time_point;
using duration = clock::duration;
duration* d_;
time_point start_;
timer(duration &d) : d_(&d), start_(clock::now()) {}
~timer(){
auto duration = clock::now() - start_;
*d_ += duration;
std::cerr << "duration: " << duration.count() << std::endl;
}
};

timer::duration f(){
timer::duration d{};
timer _(d);
std::cerr << "some heavy calculation here" << std::endl;
return d;
}

int main(){
std::cout << "function: " << f().count() << std::endl;
}

使用 clang 7.0.0 编译时,输出为:

some heavy calculation here
duration: 21642
function: 21642

而对于 g++ 8,输出是

some heavy calculation here
duration: 89747
function: 0

在这种情况下,我确实喜欢 clangs 行为,但从我在别处发现的情况来看,应该在运行析构函数之前复制返回值。

这是 Clang 的错误吗?或者这是否取决于(实现定义?)返回值优化?

无论 timer 中的 duration d 是指针还是引用,行为都是相同的。

--

我确实意识到编译器的不一致性可以通过更改 f 来解决,这样计时器的范围在返回之前就结束了,但这不是重点。

timer::duration f(){
timer::duration d{};
{
timer _(d);
std::cerr << "some heavy calculation here" << std::endl;
}
return d;
}

最佳答案

简短回答:由于 NRVO,程序的输出可能是 0 或实际持续时间。两者都有效。


背景先看:

指南:

  • 避免修改返回值的析构函数。

例如,当我们看到下面的模式时:

T f() {
T ret;
A a(ret); // or similar
return ret;
}

我们需要问自己:A::~A() 是否以某种方式修改了我们的返回值?如果是,那么我们的程序很可能存在错误。

例如:

  • 在销毁时打印返回值的类型就可以了。
  • 在销毁时计算返回值的类型不行

关于c++ - Clang 修改析构函数中的返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54565182/

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