编译器优化: 函数中的局部变量延迟销毁

我们都知道, 函数中的局部变量在函数返回时, 要被销毁. 但在实际的编译运行过程中, 编译器进行了优化, 执行过程并不按照标准步骤进行.

0. 准备工作

编写测试用的Animal类, 每个Animal对象有一个唯一的标识, Animal类的实现为(获取本文中的源码):

const bool DEBUG = true;
typedef unsigned int UINT32;

class Animal {
public:
  Animal();
  explicit Animal(const std::string &animalName);
  Animal(const Animal &rhs);
  virtual ~Animal();
  inline UINT32 getID() const;
private:
  static UINT32 idCount;
  static std::ostream &out;
  const UINT32 ID;
  std::string name;
};

每个成员函数均有相应的输出信息, 以便了解程序的执行过程. 现列出复制构造函数的实现(获取本文中的源码):

Animal::Animal(const std::string &animalName)
: ID(idCount++), name(animalName) {
  if (DEBUG) {
    out << "Animal::Animal(std::string &animalName), ID=" << ID 
      << ", name=" << name << std::endl;
  }
}

1. 测试: 最简单的测试

下面以最简单的例子来测试编译器的优化程度, 例子代码为(获取本文中的源码):

int main() {
  void test1();
  test1();
  return 0;
}

void test1() {
  Animal test1_fun1();
  Animal a = test1_fun1();
}

Animal test1_fun1() {
  return Animal("kitty");
}

在编译运行之前, 先来分析一下代码: 首先, 在函数test1_fun1中创建一个临时变量, 估且称其为temp1, 函数test1_fun1返回一个Animal类型的变量, 在退出test1_fun1函数前, 将temp1复制一份(调用复制构造函数), 称新复制的对象为temp2(作用域为main函数), 然后销毁临时变量temp1, 在main函数中, 调用a的复制构造函数(参数为temp2)进行初始化. 销毁临时变量temp2. 销毁变量a.

但实际的运行结果(VS2010, g++4.4.3)为:

Animal::Animal(std::string &animalName), ID=0, name=kitty
Animal::~Animal(), ID=0

两个Animal变量被省略了.

2. 测试: 简单的测试

修改上面test1和test1_fun1函数, 函数体中的内容改为(获取本文中的源码):

void test1() {
  Animal test1_fun1();
  Animal a = test1_fun1();
  cout << a.getID() << endl;
}

Animal test1_fun1() {
  Animal a("kitty");
  return a;
}
结果会有不同吗? 请看实际运行的结果:

VS2010的运行结果为:


ID=0的对象是test1_fun1函数中的局部变量a, 在test1_fun1函数返回后, ID=0的局部变量没有被销毁, 而是用来初始化test1中的变量, 初始化完之后, ID=0的变量被销毁.

g++4.4.3的运行结果为:

Animal::Animal(std::string &animalName), ID=0, name=kitty
0
Animal::~Animal(), ID=0

download source code:

本文中所用到的所有源码, 下载地址: http://163.fm/K2kZ9VK  提取码:9YRcWGQz

若下载次数达到上限, 请留言或通过邮件(njnu_mjn#126.com, #改为@)联系我

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值