cpp,函数返回一个局部对象。
2013-09-02 10:04
239 查看
class.cc
#include <stdio.h>
class Test {
public:
Test(int a, int b): x(a), y(b) {}
int GetX() const { return x;};
int GetY() const { return y;};
private:
int x;
int y;
};
Test foo(void)
{
Test tmp(34, 35);
return tmp;
}
int main()
{
Test ret(1, 2);
ret = foo();
printf("Test x: %d, y: %d\n", ret.GetX(), ret.GetY());
return 0;
}
g++ -S class.cc
class.s
.file "class.c"
.section .text._ZN4TestC1Eii,"axG",@progbits,_ZN4TestC1Eii,comdat
.align 2
.weak _ZN4TestC1Eii
.type _ZN4TestC1Eii, @function
_ZN4TestC1Eii:
.LFB2:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl 12(%ebp), %edx
movl %edx, (%eax)
movl 8(%ebp), %eax
movl 16(%ebp), %edx
movl %edx, 4(%eax)
popl %ebp
ret
.cfi_endproc
.LFE2:
.size _ZN4TestC1Eii, .-_ZN4TestC1Eii
.section .text._ZNK4Test4GetXEv,"axG",@progbits,_ZNK4Test4GetXEv,comdat
.align 2
.weak _ZNK4Test4GetXEv
.type _ZNK4Test4GetXEv, @function
_ZNK4Test4GetXEv:
.LFB3:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl (%eax), %eax
popl %ebp
ret
.cfi_endproc
.LFE3:
.size _ZNK4Test4GetXEv, .-_ZNK4Test4GetXEv
.section .text._ZNK4Test4GetYEv,"axG",@progbits,_ZNK4Test4GetYEv,comdat
.align 2
.weak _ZNK4Test4GetYEv
.type _ZNK4Test4GetYEv, @function
_ZNK4Test4GetYEv:
.LFB4:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl 4(%eax), %eax
popl %ebp
ret
.cfi_endproc
.LFE4:
.size _ZNK4Test4GetYEv, .-_ZNK4Test4GetYEv
.text
.globl _Z3foov
.type _Z3foov, @function
_Z3foov:
.LFB5:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
pushl %ebx
subl $36, %esp
movl 8(%ebp), %ebx
.cfi_offset 3, -12
movl $35, 8(%esp)
movl $34, 4(%esp)
movl %ebx, (%esp)
call _ZN4TestC1Eii
movl %ebx, %eax
addl $36, %esp
popl %ebx
popl %ebp
ret $4
.cfi_endproc
.LFE5:
.size _Z3foov, .-_Z3foov
.section .rodata
.LC0:
.string "Test x: %d, y: %d\n"
.text
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
.cfi_escape 0x10,0x5,0x1,0x55
pushl %ebx
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x78,0x6
subl $48, %esp
movl $2, 8(%esp)
movl $1, 4(%esp)
leal -16(%ebp), %eax
movl %eax, (%esp)
.cfi_escape 0x10,0x3,0x2,0x75,0x7c
call _ZN4TestC1Eii
leal -32(%ebp), %eax
movl %eax, (%esp)
call _Z3foov
subl $4, %esp
movl -32(%ebp), %eax
movl -28(%ebp), %edx
movl %eax, -16(%ebp)
movl %edx, -12(%ebp)
leal -16(%ebp), %eax
movl %eax, (%esp)
call _ZNK4Test4GetYEv
movl %eax, %ebx
leal -16(%ebp), %eax
movl %eax, (%esp)
call _ZNK4Test4GetXEv
movl %ebx, 8(%esp)
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, %eax
leal -8(%ebp), %esp
addl $0, %esp
popl %ecx
popl %ebx
popl %ebp
leal -4(%ecx), %esp
ret
.cfi_endproc
.LFE6:
.size main, .-main
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
我以为编译器会我弄一个析构函数,在foo函数返回前调用这个函数,汇编后发现,编译器没这么干。仔细一想,也应该是这样,这个class这么简单,data部分也没什么好构析的,退下栈,这个对象就算是没有了。如果我们这个class再复杂一点,自己写一个析构函数,就应该能看到析构函数在foo返回前被调用了。
还有返回一个局部对象很不明智,我是在一本书里面看到一个函数这么写,让我很疑惑,这么会干这么低级的事呢!
#include <stdio.h>
class Test {
public:
Test(int a, int b): x(a), y(b) {}
int GetX() const { return x;};
int GetY() const { return y;};
private:
int x;
int y;
};
Test foo(void)
{
Test tmp(34, 35);
return tmp;
}
int main()
{
Test ret(1, 2);
ret = foo();
printf("Test x: %d, y: %d\n", ret.GetX(), ret.GetY());
return 0;
}
g++ -S class.cc
class.s
.file "class.c"
.section .text._ZN4TestC1Eii,"axG",@progbits,_ZN4TestC1Eii,comdat
.align 2
.weak _ZN4TestC1Eii
.type _ZN4TestC1Eii, @function
_ZN4TestC1Eii:
.LFB2:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl 12(%ebp), %edx
movl %edx, (%eax)
movl 8(%ebp), %eax
movl 16(%ebp), %edx
movl %edx, 4(%eax)
popl %ebp
ret
.cfi_endproc
.LFE2:
.size _ZN4TestC1Eii, .-_ZN4TestC1Eii
.section .text._ZNK4Test4GetXEv,"axG",@progbits,_ZNK4Test4GetXEv,comdat
.align 2
.weak _ZNK4Test4GetXEv
.type _ZNK4Test4GetXEv, @function
_ZNK4Test4GetXEv:
.LFB3:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl (%eax), %eax
popl %ebp
ret
.cfi_endproc
.LFE3:
.size _ZNK4Test4GetXEv, .-_ZNK4Test4GetXEv
.section .text._ZNK4Test4GetYEv,"axG",@progbits,_ZNK4Test4GetYEv,comdat
.align 2
.weak _ZNK4Test4GetYEv
.type _ZNK4Test4GetYEv, @function
_ZNK4Test4GetYEv:
.LFB4:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
movl 4(%eax), %eax
popl %ebp
ret
.cfi_endproc
.LFE4:
.size _ZNK4Test4GetYEv, .-_ZNK4Test4GetYEv
.text
.globl _Z3foov
.type _Z3foov, @function
_Z3foov:
.LFB5:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
pushl %ebx
subl $36, %esp
movl 8(%ebp), %ebx
.cfi_offset 3, -12
movl $35, 8(%esp)
movl $34, 4(%esp)
movl %ebx, (%esp)
call _ZN4TestC1Eii
movl %ebx, %eax
addl $36, %esp
popl %ebx
popl %ebp
ret $4
.cfi_endproc
.LFE5:
.size _Z3foov, .-_Z3foov
.section .rodata
.LC0:
.string "Test x: %d, y: %d\n"
.text
.globl main
.type main, @function
main:
.LFB6:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
.cfi_escape 0x10,0x5,0x1,0x55
pushl %ebx
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x78,0x6
subl $48, %esp
movl $2, 8(%esp)
movl $1, 4(%esp)
leal -16(%ebp), %eax
movl %eax, (%esp)
.cfi_escape 0x10,0x3,0x2,0x75,0x7c
call _ZN4TestC1Eii
leal -32(%ebp), %eax
movl %eax, (%esp)
call _Z3foov
subl $4, %esp
movl -32(%ebp), %eax
movl -28(%ebp), %edx
movl %eax, -16(%ebp)
movl %edx, -12(%ebp)
leal -16(%ebp), %eax
movl %eax, (%esp)
call _ZNK4Test4GetYEv
movl %eax, %ebx
leal -16(%ebp), %eax
movl %eax, (%esp)
call _ZNK4Test4GetXEv
movl %ebx, 8(%esp)
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, %eax
leal -8(%ebp), %esp
addl $0, %esp
popl %ecx
popl %ebx
popl %ebp
leal -4(%ecx), %esp
ret
.cfi_endproc
.LFE6:
.size main, .-main
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
我以为编译器会我弄一个析构函数,在foo函数返回前调用这个函数,汇编后发现,编译器没这么干。仔细一想,也应该是这样,这个class这么简单,data部分也没什么好构析的,退下栈,这个对象就算是没有了。如果我们这个class再复杂一点,自己写一个析构函数,就应该能看到析构函数在foo返回前被调用了。
还有返回一个局部对象很不明智,我是在一本书里面看到一个函数这么写,让我很疑惑,这么会干这么低级的事呢!
相关文章推荐
- 关于函数的返回值是一个接口类型的对象
- 函数功能:传入一个数组,返回数组中第二大数。已知数组中的对象都是数字构成的字符串,且任意两元素不相等。 如传入:@[@"1",@"2",@"3",@"4"],返回@"3"
- 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
- 不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
- 如果一个函数中有局部对象的存在, 那么它就一定会存在 C++ 的异常处理机制
- JavaSE8基础 函数返回一个匿名对象 简单示例
- 关于C++函数返回局部对象的详细分析
- 条款 31: 千万不要返回局部对象的引用,也不要返回函数内部用 new 初始化的 指针的引用
- 接受int形参(double,,等等)返回int(...);并且一个vector对象保存指向这些函数的指针;进行加减乘除;输出结果
- 一个函数返回临时对象引起的编译器优化问题
- c++返回函数局部对象的引用
- C++对象模型之编译器如何处理函数返回一个对象
- c++返回函数局部对象的引用
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- boost::bind会返回一个函数对象,它内部保存了数据的拷贝
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- cpp函数返回对象&&数组
- 函数 千万不要返回“局部对象”的引用或者指针
- 【问题记录】python 函数 传入一个对象返回一个对象值得注意
- C++函数返回一个对象学习笔记