函数调用传形参,何时才会创建临时变量?
源代码:
#include <string>
#include <iostream>
using namespace std;
string version1(string s1, string s2);
int main()
{
string input="unix";
string input2="***";
string result;
result = version1(input, input2);
return 0;
}
string version1(string s1, string s2)
{
s1 = s2 + s1 + s2;
return s1;
}
main 函数中作出临时变量的代码
0x0000000000400a7e <+106>: callq 0x400850 <_ZNSsC1Ev@plt>
0x0000000000400a83 <+111>: lea -0x60(%rbp),%rdx
0x0000000000400a87 <+115>: lea -0x30(%rbp),%rax
0x0000000000400a8b <+119>: mov %rdx,%rsi
0x0000000000400a8e <+122>: mov %rax,%rdi
0x0000000000400a91 <+125>: callq 0x400880 <_ZNSsC1ERKSs@plt>
0x0000000000400a96 <+130>: lea -0x70(%rbp),%rdx
0x0000000000400a9a <+134>: lea -0x40(%rbp),%rax
0x0000000000400a9e <+138>: mov %rdx,%rsi
0x0000000000400aa1 <+141>: mov %rax,%rdi
0x0000000000400aa4 <+144>: callq 0x400880 <_ZNSsC1ERKSs@plt>
0x0000000000400aa9 <+149>: lea -0x20(%rbp),%rax
0x0000000000400aad <+153>: lea -0x30(%rbp),%rdx
0x0000000000400ab1 <+157>: lea -0x40(%rbp),%rcx
0x0000000000400ab5 <+161>: mov %rcx,%rsi
0x0000000000400ab8 <+164>: mov %rax,%rdi
0x0000000000400abb <+167>: callq 0x400bc3 <version1(std::string, std::string)>
红色字体为复制input的临时变量,蓝色字体为复制input2的临时变量
version1中收input和input1的代码:
Dump of assembler code for function version1(std::string, std::string):
0x0000000000400bc3 <+0>: push %rbp
0x0000000000400bc4 <+1>: mov %rsp,%rbp
0x0000000000400bc7 <+4>: push %rbx
0x0000000000400bc8 <+5>: sub $0x48,%rsp
0x0000000000400bcc <+9>: mov %rdi,-0x38(%rbp)
0x0000000000400bd0 <+13>: mov %rsi,-0x40(%rbp)
0x0000000000400bd4 <+17>: mov %rdx,-0x48(%rbp)
0x0000000000400bd8 <+21>: lea -0x30(%rbp),%rax
0x0000000000400bdc <+25>: mov -0x40(%rbp),%rdx // copy of input
0x0000000000400be0 <+29>: mov -0x48(%rbp),%rcx // copy of input2
调用version1 函数后的堆栈情况:
0x7fffffffe0c0: 0xffffe270 0x00007fff 0xffffe160 0x00007fff
0x7fffffffe0d0: 0xffffe150 0x00007fff 0xffffe170 0x00007fff
0x7fffffffe0e0: 0xffffe130 0x00007fff 0xffffe130 0x00007fff
0x7fffffffe0f0: 0xffffe160 0x00007fff 0x00000003 0x00000000
0x7fffffffe100: 0x00000010 0x00000000 0x00000000 0x00000000
0x7fffffffe110: 0xffffe190 0x00007fff 0x00400ac0 0x00000000
0x7fffffffe120: 0x00603028 0x00000000 0x00400cb8 0x00000000
0x7fffffffe130: 0x00603058 0x00000000 0x0000ffff 0x00000001
0x7fffffffe140: 0xf7dc74d8 0x00007fff 0x00400ccd 0x00000000
0x7fffffffe150: 0x00603028 0x00000000 0x00400d9d 0x00000000
0x7fffffffe160: 0x00603058 0x00000000 0x00400d40 0x00000000
0x7fffffffe170: 0x00000000 0x00000000 0x00400930 0x00000000
0x7fffffffe180: 0xffffe270 0x00007fff 0x00000000 0x00000000
0x7fffffffe190: 0x00000000 0x00000000 0xf752576d 0x00007fff
0x7fffffffe1a0: 0x00000000 0x00000000 0xffffe278 0x00007fff
0x7fffffffe110: version1 栈顶
0x7fffffffe190: main 栈顶
0x7fffffffe120: main input
0x7fffffffe130: main input2
0x7fffffffe150: copy of main input (临时变量1)
0x7fffffffe160: copy of main input2 (临时变量2)
很清楚的看到 字符串被拷贝了一份后传给了version , 而上述代码如果将string 换为int则完全不会拷贝临时变量传给version,c++传形参时何时创建临时变量,何时不创建,有何规则可依据吗?