复制elision以传递值传递参数 [英] Copy elision for pass-by-value arguments

查看:112
本文介绍了复制elision以传递值传递参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定

struct Range{
    Range(double from, double to) : from(from), to(to) {}
    double from;
    double to;
};

struct Box{
    Box(Range x, Range y) : x(x), y(y) {}
    Range x;
    Range y;
};

假设我们运行框框(Range(0.0,1.0),Range 0.0,2.0))

一个具有优化功能的现代编译器能够避免复制 Range 对象在这个建设过程中? (即构造 Range 对象以开头?)

Could a modern compiler with optimizations enabled avoid copying Range objects altogether during this construction? (i.e. construct the Range objects inside box to begin with?)

推荐答案

实际上,在传递给构造函数的每个 Range 对象上执行两个副本。第一次将临时 Range 对象复制到函数参数中时发生。这可以根据101010的答案中给出的参考文献省略。有特定情况可以执行复印检查。

There are actually two copies being performed on each Range object passed to the constructor. The first happens when copying the temporary Range object into the function parameter. This can be elided as per the reference given in 101010's answer. There are specific circumstances in which copy elision can be performed.

第二个副本发生在将函数参数复制到成员(如构造函数初始化列表中指定的)时。这不能被省略,这就是为什么你仍然看到为YSC的答案中的每个参数做一个单一的副本。

The second copy happens when copying the function parameter into the member (as specified in the constructor initialization list). This cannot be elided, and this is why you still see a single copy being made for each parameter in YSC's answer.

当复制构造函数有副作用

When the copy constructor has side-effects (such as the prints in YSC's answer), copy elision can still be performed for the first copy, but the second copy must remain.

但是,编译器总是可以自由地进行更改如果他们不改变程序的观察行为(这被称为as-if规则)。这意味着如果复制构造函数没有副作用,并且删除构造函数调用不会改变结果,编译器可以自由删除甚至第二个副本。

However, the compiler is always free to make changes if they do not alter the observed behavior of the program (this is known as the "as-if" rule). This means that if the copy constructor has no side effects and removing the constructor call will not change the result, the compiler is free to remove even the second copy.

通过分析生成的程序集来看这个。在此示例中,编译器不仅优化了副本,而且还优化了 Box object本身:

You can see this by analyzing the generated assembly. In this example, the compiler optimizes out not only the copies, but even the construction of the Box object itself:

Box box(Range(a,b),Range(c,d));
std::cout << box.x.from;

生成相同的程序集:

std::cout << a;

这篇关于复制elision以传递值传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆