关于函数返回值产生临时变量的问题

时间:2022-06-08 02:21:48
int fun(int i)
{
  int p = i*i
  return p;
}
int main()
{
  int m = fun(5);
}

昨天晚上看到的一个帖子, 说是fun函数返回时会产生一个临时变量, 再将这个临时变量赋值给m, 我觉得应该不产生临时变量了呀, 谁能给我说说这方面的知识, 或者哪里有说这个的

9 个解决方案

#1


thinking in c++

#2


对于值类型,是没问题的,对于指针是不可以的

#3


应该会返回一个临时变量。请参考拙作:
关于函数返回值的几种情况

并请指正:)

#4



int m = fun(5);

00412EE2  call        fun (4111BDh) 
00412EE7  add         esp,4 
00412EEA  mov         dword ptr [ebp-18h],eax 




int fun(int i)
{
00412E60  push        ebp  
00412E61  mov         ebp,esp 
00412E63  sub         esp,0CCh 
00412E69  push        ebx  
00412E6A  push        esi  
00412E6B  push        edi  
00412E6C  lea         edi,[ebp-0CCh] 
00412E72  mov         ecx,33h 
00412E77  mov         eax,0CCCCCCCCh 
00412E7C  rep stos    dword ptr es:[edi] 
int p = i*i;
00412E7E  mov         eax,dword ptr [i] 
00412E81  imul        eax,dword ptr [i] 
00412E85  mov         dword ptr [p],eax 
return p;
00412E88  mov         eax,dword ptr [p] 
}

看eax,算中间变量不,哈哈

#5


一般对于int这样的类型,直接将返回值存放的eax寄存器,然后从寄存器move到m里面就是了。当然正常来说是需要一个临时变量保存,然后在从临时变量move到m

#6


哦, 谢谢各位

#7



int fun(int i)
{
  int p = i*i;
  return p;
}
int main()
{
  int m = fun(5);
}

C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过eax:edx寄存器对保存,大于64位采用则调用者把返回值存放的地址当做函数的第一个参数压入堆栈调用,在执行函数中直接把返回值存放在对应地址)。

对于C++的非POD(Plain Old Data)数据类型,牵扯到构造和析构的过程,因此会造成效率浪费。实际上编译器会做优化,就如同C语言中大于64位时返回值的传递一样。

对于本例代码,如果编译器不做任何优化,则执行i*i保存到p,然后p传递到寄存器eax,最后返回,call结束后,main函数中把eax寄存器拷贝回局部变量m。

#8


难怪我用C写的时候并未发现它调用拷贝构造函数生成临时变量
是否就是你说的优化?
引用 7 楼 cppgp 的回复:
C/C++ code

int fun(int i)
{
  int p = i*i;
  return p;
}
int main()
{
  int m = fun(5);
}


C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过eax:edx寄存器对保存,大于64位采用则调用者把返回值存放的地址当做函数的第一个参数压入堆栈调用,在执行函数中直接把返回值存放在对……

#9


笔误
C++
引用 8 楼 q191201771 的回复:
难怪我用C写的时候并未发现它调用拷贝构造函数生成临时变量
是否就是你说的优化?引用 7 楼 cppgp 的回复:

C/C++ code

int fun(int i)
{
int p = i*i;
return p;
}
int main()
{
int m = fun(5);
}


C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过e……

#1


thinking in c++

#2


对于值类型,是没问题的,对于指针是不可以的

#3


应该会返回一个临时变量。请参考拙作:
关于函数返回值的几种情况

并请指正:)

#4



int m = fun(5);

00412EE2  call        fun (4111BDh) 
00412EE7  add         esp,4 
00412EEA  mov         dword ptr [ebp-18h],eax 




int fun(int i)
{
00412E60  push        ebp  
00412E61  mov         ebp,esp 
00412E63  sub         esp,0CCh 
00412E69  push        ebx  
00412E6A  push        esi  
00412E6B  push        edi  
00412E6C  lea         edi,[ebp-0CCh] 
00412E72  mov         ecx,33h 
00412E77  mov         eax,0CCCCCCCCh 
00412E7C  rep stos    dword ptr es:[edi] 
int p = i*i;
00412E7E  mov         eax,dword ptr [i] 
00412E81  imul        eax,dword ptr [i] 
00412E85  mov         dword ptr [p],eax 
return p;
00412E88  mov         eax,dword ptr [p] 
}

看eax,算中间变量不,哈哈

#5


一般对于int这样的类型,直接将返回值存放的eax寄存器,然后从寄存器move到m里面就是了。当然正常来说是需要一个临时变量保存,然后在从临时变量move到m

#6


哦, 谢谢各位

#7



int fun(int i)
{
  int p = i*i;
  return p;
}
int main()
{
  int m = fun(5);
}

C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过eax:edx寄存器对保存,大于64位采用则调用者把返回值存放的地址当做函数的第一个参数压入堆栈调用,在执行函数中直接把返回值存放在对应地址)。

对于C++的非POD(Plain Old Data)数据类型,牵扯到构造和析构的过程,因此会造成效率浪费。实际上编译器会做优化,就如同C语言中大于64位时返回值的传递一样。

对于本例代码,如果编译器不做任何优化,则执行i*i保存到p,然后p传递到寄存器eax,最后返回,call结束后,main函数中把eax寄存器拷贝回局部变量m。

#8


难怪我用C写的时候并未发现它调用拷贝构造函数生成临时变量
是否就是你说的优化?
引用 7 楼 cppgp 的回复:
C/C++ code

int fun(int i)
{
  int p = i*i;
  return p;
}
int main()
{
  int m = fun(5);
}


C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过eax:edx寄存器对保存,大于64位采用则调用者把返回值存放的地址当做函数的第一个参数压入堆栈调用,在执行函数中直接把返回值存放在对……

#9


笔误
C++
引用 8 楼 q191201771 的回复:
难怪我用C写的时候并未发现它调用拷贝构造函数生成临时变量
是否就是你说的优化?引用 7 楼 cppgp 的回复:

C/C++ code

int fun(int i)
{
int p = i*i;
return p;
}
int main()
{
int m = fun(5);
}


C语言调用函数时,如果返回值是32位的,则通过寄存器eax传递(64位通过e……