想像: S f(S a) { return a; } 为什么不允许别名和返回值插槽? S s = f(t); S s = t; // can't generally transform it to this 🙁 如果S的拷贝构造函数有副作用,spec不允许这个转换。 相反,它需要至less两个副本(一个从t到a ,一个从a到返回值,另一个从返回值到s ,只有最后一个可以被忽略。代表t到f的拷贝的事实,唯一的拷贝在移动/拷贝构造函数的副作用的存在下仍然是强制性的)。 这是为什么?
我需要在命令行上使用哪些标志来禁用g ++编译器自动启用的返回值优化?
有些人没有意识到可以按C中的值传递和返回结构 。 我的问题是关于在C中返回结构时编译器做不必要的拷贝。像GCC这样的C编译器使用返回值优化(RVO)优化还是C ++唯一的概念? 我所读到的关于RVO和copy elision的一切都是关于C ++的。 我们来看一个例子。 我目前正在C中实现一个double-double数据types (或者浮动浮动开始,因为我发现很容易unit testing)。 考虑下面的代码。 typedef struct { float hi; float lo; } doublefloat; doublefloat quick_two_sum(float a, float b) { float s = a + b; float e = b – (s – a); return (doublefloat){s, e}; } 编译器是否会创build我返回的doublefloat值的临时副本,或者临时副本是否可以被删除? 那么C中的命名返回值优化(NRVO)呢? 我有另一个function doublefloat df64_add(doublefloat a, doublefloat b) { doublefloat […]
什么是复制elision? 什么是(命名)返回值优化? 他们意味着什么? 在什么情况下可以发生? 什么是限制? 如果你是参考这个问题,你可能正在寻找介绍 。 有关技术概述,请参阅标准参考 。 在这里查看常见情况 。
请考虑三个function。 std::string get_a_string() { return "hello"; } std::string get_a_string1() { return std::string("hello"); } std::string get_a_string2() { std::string str("hello"); return str; } 在所有这三种情况下RVO会被应用吗? 在上面的代码中返回一个临时值是否可以? 我相信这是可以的,因为我是以价值回报它,而不是返回任何参考。 有什么想法吗?
简短版本:在许多编程语言中返回大型对象(如向量/数组)很常见。 如果这个类有一个移动构造函数,或者C ++程序员认为它是奇怪/丑陋/可憎的,现在这种风格现在可以被C ++ 0x接受吗? 长版本:在C + + 0x这是仍然认为不好的forms? std::vector<std::string> BuildLargeVector(); … std::vector<std::string> v = BuildLargeVector(); 传统版本看起来像这样: void BuildLargeVector(std::vector<std::string>& result); … std::vector<std::string> v; BuildLargeVector(v); 在较新的版本中,从BuildLargeVector返回的值是一个右值,因此v将使用std::vector的移动构造函数构造,假设(N)RVO不会发生。 甚至在C ++ 0x之前,由于(N)RVO,第一种forms往往是“高效的”。 但是,(N)RVO由编译器自行决定。 现在我们有了右值引用, 保证不会发生深度复制。 编辑 :问题实际上不是关于优化。 所显示的两种forms在现实世界的程序中都具有几乎相同的性能。 而过去,第一种forms的performance可能会有数量级的下滑。 因此,第一种forms在很长一段时间里是C ++编程中的主要代码异味。 现在不行了,我希望?