g++编译优化选项-fno-elide-constructors

1、考虑下面的代码,请问输出结果是什么?

#include <stdio.h>

class A {
public:
	A(int val) {
		puts("A(int)");
		d = val;
	}
	A(A&& a) {
		puts("A(A&&)");
		d = a.d;
	}
	A(A& a) {
		puts("A(A&)");
		d = a.d;
	}
	~A() {}
private:
	int d;
};
A create_A(int val) {
	return A(val);
}
int main(void) {
	A a{create_A(5)};

	return 0;
}

如果你认为应该输出下面的结果,那就不用继续往下看了。

$ g++ ./main.cpp
$ ./a.out
A(int)

2、对于上面的输出结果,是不是或多或少有点出乎意料。从输出结果来看,只调用了一次构造函数,而且 移动构造函数 和 拷贝构造函数 都没有被调用。为什么会这样?是因为编译器对返回值做了优化,何以见得?我们可以打印一下create_A()中临时对象的地址,然后再打印一下main函数中对象a的地址,会发现他们是一样的。

#include <stdio.h>

class A {
public:
	A(int val) {
		puts("A(int)");
		d = val;
	}
	A(A&& a) {
		puts("A(A&&)");
		d = a.d;
	}
	A(A& a) {
		puts("A(A&)");
		d = a.d;
	}
	~A() {}
private:
	int d;
};
A create_A(int val) {
	A a(val);
	printf("create_A()::&a = %p\n", &a);
	return a;
}
int main(void) {
	A a{create_A(5)};
	printf("main()::&a = %p\n", &a);

	return 0;
}

程序运行结果如下:

$ g++ ./main.cpp
$ ./a.out
A(int)
create_A()::&a = 0x7ffee7bd08f8
main()::&a = 0x7ffee7bd08f8

3、如果开启了-fno-elide-constructors编译选项,结果就更容易理解了

$ g++ -fno-elide-constructors main.cpp
$ ./a.out
A(int)
create_A()::&a = 0x7ffee73018b8
A(A&&)
A(A&&)
main()::&a = 0x7ffee73018f8

从输出结果来看,拷贝构造函数被调用了两次,一次是create_A()内部创建的对象返回后构造一个临时对象产生的,另一次是在main函数中构造对象a产生的,同时,create_A()中对象a的地址与main函数中对象a的地址不相同。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值