本文介绍了为什么通过引用传递结构不是一种常见的优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直到今天,我一直认为体面的编译器会自动将 struct pass-by-value 转换为 pass-by-reference,如果结构足够大,后者会更快.据我所知,这似乎是一个不费吹灰之力的优化.然而,为了满足我对这是否真的发生的好奇心,我在 C++ 和 D 并查看了 GCC 和 Digital Mars D 的输出.两者都坚持按值传递 32 字节结构,而所有有问题的函数只是将成员相加并返回值,而没有修改传递的结构in. C++ 版本如下.

Up until today, I had always thought that decent compilers automatically convert struct pass-by-value to pass-by-reference if the struct is large enough that the latter would be faster. To the best of my knowledge, this seems like a no-brainer optimization. However, to satisfy my curiosity as to whether this actually happens, I created a simple test case in both C++ and D and looked at the output of both GCC and Digital Mars D. Both insisted on passing 32-byte structs by value when all the function in question did was add up the members and return the values, with no modification of the struct passed in. The C++ version is below.

#include "iostream.h"

struct S {
    int i, j, k, l, m, n, o, p;
};

int foo(S s) {
    return s.i + s.j + s.k + s.l + s.m + s.n + s.o + s.p;
}

int main() {
    S s;
    int bar = foo(s);
    cout << bar;
}

我的问题是,为什么编译器不优化这样的东西以传递引用而不是实际将所有那些 int 推入堆栈?

My question is, why the heck wouldn't something like this be optimized by the compiler to pass-by-reference instead of actually pushing all those ints onto the stack?

注意:使用的编译器开关:GCC -O2(-O3 内联 foo().),DMD -O -inline -release.

Note: Compiler switches used: GCC -O2 (-O3 inlined foo().), DMD -O -inline -release.

显然,在一般情况下,按值传递与按引用传递的语义不会相同,例如是否涉及复制构造函数或在被调用者中修改了原始结构.然而,在许多现实世界的场景中,语义在可观察行为方面是相同的.这些是我要询问的案例.

Obviously, in the general case the semantics of pass-by-value vs. pass-by-reference won't be the same, such as if copy constructors are involved or the original struct is modified in the callee. However, in a lot of real-world scenarios, the semantics will be identical in terms of observable behavior. These are the cases I'm asking about.

推荐答案

不要忘记,在 C/C++ 中,编译器需要能够仅根据函数声明编译对函数的调用.

Don't forget that in C/C++ the compiler needs to be able to compile a call to a function based only on the function declaration.

鉴于调用者可能只使用该信息,编译器无法编译函数以利用您所说的优化.调用者不知道该函数不会修改任何内容,因此它不能通过 ref 传递.由于某些调用者可能由于缺乏详细信息而传值,因此必须在编译函数时假设传值,并且每个人都需要传值.

Given that callers might be using only that information, there's no way for a compiler to compile the function to take advantage of the optimization you're talking about. The caller can't know the function won't modify anything and so it can't pass by ref. Since some callers might pass by value due to lack of detailed information, the function has to be compiled assuming pass-by-value and everybody needs to pass by value.

请注意,即使您将参数标记为 'const',编译器仍然无法执行优化,因为函数可能会撒谎并丢弃 const (这是允许的,很好- 只要传入的对象实际上不是 const 就定义).

Note that even if you marked the parameter as 'const', the compiler still can't perform the optimization, because the function could be lying and cast away the constness (this is permitted and well-defined as long as the object being passed in is actually not const).

我认为对于静态函数(或匿名命名空间中的函数),编译器可能会进行您所说的优化,因为该函数没有外部链接.只要函数的地址没有传递给其他例程或存储在指针中,它就不能被其他代码调用.在这种情况下,编译器可以完全了解所有调用者,所以我想它可以进行优化.

I think that for static functions (or those in an anonymous namespace), the compiler could possibly make the optimization you're talking about, since the function does not have external linkage. As long as the address of the function isn't passed to some other routine or stored in a pointer, it should not be callable from other code. In this case the compiler could have full knowledge of all callers, so I suppose it could make the optimization.

我不确定是否有(实际上,如果有的话我会感到惊讶,因为它可能不会经常应用).

I'm not sure if any do (actually, I'd be surprised if any do, since it probably couldn't be applied very often).

当然,作为程序员(使用 C++ 时),您可以通过使用 const& 参数强制编译器执行此优化.我知道你在问为什么编译器不能自动完成,但我想这是下一个最好的事情.

Of course, as the programmer (when using C++) you can force the compiler to perform this optimization by using const& parameters whenever possible. I know you're asking why the compiler can't do it automatically, but I suppose this is the next best thing.

这篇关于为什么通过引用传递结构不是一种常见的优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-01 23:30