什么是 foo() = "test" ;男孩



在探索编译器如何处理C++中的字符串时,我尝试了以下程序,该程序编译并运行时没有错误,但我不明白它是否更改了任何内存位置或对程序流有任何影响。它似乎没有任何作用。

#include <iostream>
using namespace std;
string str = "this is public stringn";
string foo() {
return str;
}
int main()
{
foo() = "test";       //  what does this line do
cout << str << endl;
char c;
cin>>c;
return 0;
}

它确实生成了一些汇编指令,但我不知道它们是做什么的

getString() = "test";       //  what does this line do
00007FF68B0D6F1B  lea         rcx,[rbp+0E8h]  
00007FF68B0D6F22  call        getString (07FF68B0D1640h)  
00007FF68B0D6F27  mov         qword ptr [rbp+118h],rax  
00007FF68B0D6F2E  mov         rax,qword ptr [rbp+118h]  
00007FF68B0D6F35  mov         qword ptr [rbp+120h],rax  
00007FF68B0D6F3C  lea         rdx,[string "test" (07FF68B0E1584h)]  
00007FF68B0D6F43  mov         rcx,qword ptr [rbp+120h]  
00007FF68B0D6F4A  call std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator= (07FF68B0D1037h)  
00007FF68B0D6F4F  nop  
00007FF68B0D6F50  lea         rcx,[rbp+0E8h]  
00007FF68B0D6F57  call  std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> > (07FF68B0D1140h) 
cout << str << endl;

本质上,它没有做任何有用的事情。

foo函数返回字符串str副本,并分配给该副本。类似于:

{
string temp;
temp = foo();
temp = "test";
// Here the temp object is destructed, and the modifications
// made to it are lost
}

因为该语句没有任何可观察到的效果,所以"好像"规则不仅允许编译器跳过赋值,还允许编译器跳过对foo本身的调用。


如果foo函数向str对象返回引用,情况将大不相同:

string& foo() {
return str;
}

因为这样分配会分配给实际的str对象:

{
string& temp_ref = foo();
temp_ref = "test";  // Really assigns to str
}

foo()返回str的副本。

foo() = "test";

这一行将副本的内容更改为";测试";但不会将其存储在任何地方,因此它实际上什么都不做。

最新更新