c – 左值引用是否与左值引用具有相同的开销?

前端之家收集整理的这篇文章主要介绍了c – 左值引用是否与左值引用具有相同的开销?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑这个例子:
#include <utility>

// runtime dominated by argument passing
template <class T>
void foo(T t) {}

int main() {
    int i(0);
    foo<int>(i); // fast -- int is scalar type
    foo<int&>(i); // slow -- lvalue reference overhead
    foo<int&&>(std::move(i)); // ???
}

foo< int&&>(i)和foo< int>(i)一样快,还是像foo< int&>(i)那样涉及指针开销?

编辑:正如所建议的,运行g -S给了我相同的51行汇编文件foo< int>(i)和foo< int&>(i),但foo< int&&>(std :: move(i))产生了71行汇编代码(看起来差异来自std :: move).

编辑:感谢那些推荐具有不同优化级别的g -S的人 – 使用-O3(以及制作foo noinline),我能够获得看起来像xaxxon’s solution输出.

解决方法

在您的具体情况下,它们可能都是一样的.来自godbolt与gcc -O3的结果代码https://godbolt.org/g/XQJ3Z4
#include <utility>

// runtime dominated by argument passing
template <class T>
int foo(T t) { return t;}

int main() {
    int i{0};
    volatile int j;
    j = foo<int>(i); // fast -- int is scalar type
    j = foo<int&>(i); // slow -- lvalue reference overhead
    j = foo<int&&>(std::move(i)); // ???
}

是:

mov     dword ptr [rsp - 4],0 // foo<int>(i);
    mov     dword ptr [rsp - 4],0 // foo<int&>(i);
    mov     dword ptr [rsp - 4],0 // foo<int&&>(std::move(i)); 
    xor     eax,eax
    ret

volatile int使得编译器无法优化掉所有代码,因为它会知道调用的结果被丢弃,整个程序将优化为空.

但是,如果你强制函数不被内联,那么事情会改变一点int __attribute __((noinline))foo(T t){return t;}:

int foo<int>(int):                           # @int foo<int>(int)
        mov     eax,edi
        ret
int foo<int&>(int&):                          # @int foo<int&>(int&)
        mov     eax,dword ptr [rdi]
        ret
int foo<int&&>(int&&):                          # @int foo<int&&>(int&&)
        mov     eax,dword ptr [rdi]
        ret

上图:https://godbolt.org/g/pbZ1BT

对于这样的问题,学会爱https://godbolt.orghttps://quick-bench.com/(快速工作台要求你学习如何正确使用谷歌测试)

原文链接:https://www.f2er.com/c/111528.html

猜你在找的C&C++相关文章