Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 做C++;编译器将pass-by-const参考POD参数优化为pass-by-copy?_C++_Optimization - Fatal编程技术网

C++ 做C++;编译器将pass-by-const参考POD参数优化为pass-by-copy?

C++ 做C++;编译器将pass-by-const参考POD参数优化为pass-by-copy?,c++,optimization,C++,Optimization,考虑以下几点: struct Point {double x; double y;}; double complexComputation(const& Point p1, const Point& p2) { // p1 and p2 used frequently in computations } 编译器是否优化了“按引用传递”到“按副本传递”以防止频繁取消引用?换句话说,将complexComputation转换为: double complexComputa

考虑以下几点:

struct Point {double x; double y;};

double complexComputation(const& Point p1, const Point& p2)
{
    // p1 and p2 used frequently in computations
}
编译器是否优化了“按引用传递”到“按副本传递”以防止频繁取消引用?换句话说,将
complexComputation
转换为:

double complexComputation(const& Point p1, const Point& p2)
{
    double x1 = p1.x; double x2 = p2.x;
    double y1 = p1.y; double y2 = p2.y;
    // x1, x2, y1, y2 stored in registers and used frequently in computations
}
因为Point是一个POD,所以在打电话的人背后复制不会有任何副作用,对吗

如果是这样的话,那么我总是可以通过const引用传递POD对象,不管它有多小,并且不必担心最佳传递语义。对吧?

编辑:
我对GCC编译器特别感兴趣。我想我可能需要编写一些测试代码并查看ASM。

我不能代表每个编译器,但一般的答案是否定的。它不会进行优化

<>请参阅C++中如何将CuxtoCase> const 不影响某些人可能会想到的优化。

< P>如果需要,编译器可以将点成员变量绝对提升到寄存器中。但是,这与编译器将函数调用本身转换为传递值不同

您应该检查生成的程序集,以查看正在进行哪些优化

而FWIW,我使用的一般规则是,在可能的情况下,通过值传递所有的primative类型,通过const引用传递所有的class/udt(pod或not),并让编译器选择最好的方法。我们不必担心编译器正在做什么的细节,它比我们聪明得多。

有两个问题

首先,编译器不会将pass-by-ref转换为pass-by-value,特别是当
complexComputation
不是
static
(即可由外部对象使用)时

原因是API兼容性。对于CPU来说,没有所谓的“参考”。编译器将把引用转换为指针。参数通过堆栈或寄存器传递,因此调用
complexComputation
的代码可能会被调用为(假设
double
的长度暂时为4):

只有8个字节被推送到堆栈上

另一方面,passbycopy将把整个结构推到堆栈上,因此汇编代码看起来像

push x1    ; push a copy of p1.x onto the stack
push y1    ; push a copy of p1.y onto the stack
push x2    ; push a copy of p2.x onto the stack
push y2    ; push a copy of p2.y onto the stack
call complexComputation
请注意,这次16个字节被推送到堆栈上,内容是数字,而不是指针。如果
complexComputation
更改其参数传递语义,输入将变成垃圾,您的程序可能会崩溃


另一方面,优化

double complexComputation(const Point& p1, const Point& p2) {
    double x1 = p1.x; double x2 = p2.x;
    double y1 = p1.y; double y2 = p2.y;
    // x1, x2, y1, y2 stored in registers and used frequently in computations
}
这很容易做到,因为编译器可以识别经常使用的变量,并且 将它们存储到保留寄存器中(例如ARM体系结构中的r4~r13,以及许多sXX/dXX寄存器),以便更快地访问



毕竟,如果你想知道编译器是否做了一些事情,你可以随时反汇编生成的对象并进行比较。

我试图搜索这个问题,但我不断地找到关于通过值传递、通过引用传递等abc的答案。如果已经讨论过,我很抱歉。通常,相反的方法可能是更好的方法(). 传递值,并让编译器在需要时将其转换为传递引用。除非基准测试/评测告诉我们,否则我同意不要担心。但我只是好奇编译器是否真的可以进行这种类型的优化。
double complexComputation(const Point& p1, const Point& p2) {
    double x1 = p1.x; double x2 = p2.x;
    double y1 = p1.y; double y2 = p2.y;
    // x1, x2, y1, y2 stored in registers and used frequently in computations
}