Pascal 有个 result 能访问返回值对象。若函数不是类方法则函数名也可这么用。

Copy elision - cppreference.com 看这里的话 C++17 还没有把 NRVO 强制化,也就是说还不能确保 return 前能构造好返回对象。为何 C 和 C++ 没有强制在 return 前访问返回对象的做法,这算不算是设计缺陷?为什么这么多年来一直不加上呢?


语言特性层面的返回值优化对 C 程序没什么意义,反正 C 也没有构造函数,直接返回一个局部变数让编译器自己优化就行了。

在 C++ 中,强制 NRVO 确实是一个很有用的特性。比如有某个既无法 copy 也无法 move 的类,想要构造一个这个类的对象,在上面进行一些操作,然后再返回。这种时候只能依靠强制 NRVO。

而且强制 NRVO 并非完全不可实现,只需要加上一些限制。比如:

  1. 返回对象必须用特定语法显式构造。例如 returning Type identifier(args); 这样。返回对象和其他局部变数一样拥有自动生存期。
  2. 返回对象析构前必须有一条一定会执行的 return 语句,否则产生编译期错误。当然也可以规定成在返回对象的 scope 结束前自动插入一条 return,除了容易把程序员坑了之外没什么毛病。
  3. 在返回对象的生存期内的 return 语句不允许再带表达式,只能返回该对象。
  4. 在返回对象的生存期内不允许声明另一个返回对象。

不过说实话,和强制 RVO 比起来,这个设计简直丑爆了,而且很不 C++。在有大佬想出更优雅的方案之前,强制 NRVO 大概确实没法进入标准,做成编译器扩展倒是有可能。


不太明白,如果我要返回一个类,但类需要通过int做参数构造,那么这个result怎么初始化?擅作主张拿int的默认值0初始化吗?

更严重一点,万一这个这个类需要通过某些资源来构造呢,这些资源怎么来?一点点从根源构造起来?(然后发现有好几种可行的构造方式)还是说把赋值之前的操作当ub(那还有什么用)?不太能理解pascal里result的作用,看到似乎还能放在赋值操作右边当递归?
好像一开始pascal没有return的语句,不知道现在有没有,估计是没有的,因为pascal的严谨语法,只允许一个函数出口。所以只好用函数名或者result。既然c/c++的return能返回结果,并且功能更加强大,还需要result吗?后续语言C#和java都一样没有result这样的语法支持


result_t f(bool x) {
// 如果在这里能访问返回值变数,那么在这里,返回值变数是哪一个,res1 还是 res2
if (x) {
result_t res1;
return res1;
} else {
result_t res2;
return res2;
}
}


其实构造函数不就是这样。函数内可以直接操作this指针,完全可以把这个this看作是构造函数返回值的地址。(虽然构造函数没有返回值)


因为C是汇编的高级形式
c++用拷贝构造函数可以在return之前对其访问

void foo()
{
A a;
return a;
}

像这种情况如果A写了拷贝构造就会在return之前自动进入拷贝构造函数


有什么用。。
推荐阅读:
相关文章