编译器发射std :: move()运行时调用

Compiler emits std::move() runtime call?

本文关键字:运行时 调用 move 发射 std 编译器      更新时间:2023-10-16

假设以下代码:

// main.cpp
#include <iostream>
#include <string>
#include <utility>
using std::cout;
using std::string;
void print(string && s)
{
    cout << s << 'n';
}
int main()
{
    string sso{"With SSO"};
    string no_sso{"This string is much too large to have SSO, much too large"};
    print(std::move(sso));
    print(std::move(no_sso));
}

g++ -g -Wall -Wpedantic -std=c++14 -o move_poc main.cpp编译(使用MSYS2和Ubuntu上的G /Clang 相似(。

查看objdump -d -l -S move_poc的OUPUT,我们得到了:

   print(std::move(sso));
c5f:    48 8d 45 a0             lea    -0x60(%rbp),%rax
c63:    48 89 c7                mov    %rax,%rdi
c66:    e8 05 01 00 00          callq  d70
_ZSt4moveIRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEONSt16remove_referenceIT_E4typeEOS8_
c6b:    48 89 c7                mov    %rax,%rdi
c6e:    e8 47 ff ff ff          callq  bba 
_Z5printONSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

c++filt告诉我们,第一个修理符号是(编辑为简短(

std::remove_reference<...>::type&& std::move<...>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)

我的理解是,std :: move((在运行时没有生成任何东西,我将其解释为" std :: move((是编译时间操作"。看着上面产生的组件,看来我弄错了。

std :: move((应该在运行时做任何事情吗?或者,由于使用-O2编译了此通话,这仅仅是由于没有优化而进行编译的结果?

我的理解是,std :: move((在运行时没有生成任何东西,我将其解释为" std :: move((是编译时间操作"。看着上面产生的组件,看来我弄错了。

不,您正确地知道了,但它仍然是一个功能调用,并且在优化的情况下,故意关闭编译器并不会删除其他"毫无意义"的呼叫。这是为了帮助调试。

这也是为什么"优化"是此汇编模式的不良描述;这更像是"使目标代码比原始源代码相似,远远超过了实际所需的内容"。"优化开启"的真实含义是"在将程序的抽象描述转化为可以以有用和有效的方式执行的真实的事物的正确工作"。当然,在15世纪,C程序是对您想要执行计算机执行的操作的分步描述,而在此过程中,"优化"在此过程中有些有意义&Hellip;但这已经很长一段时间了。

std :: move((应该在运行时执行任何操作?

no,它的效果纯粹是"编译时间",因为它评估了您给出的表达式,但具有不同的值类别(纯粹是"编译时"概念(。它实际上没有"做"任何事情。

或,由于使用-o2汇编而删除了这个呼叫,这仅仅是由于没有优化而进行编译的结果?

是。