本文是Inside The C++ Object Model Chapter 2 部分的读书笔记。是讨论编译器调用拷贝构造函数时的策略(如何优化以提高效率),侯捷称之为"程序转化的语义学"
或者说是是关于编译器对于程序是如何进行有效转化或者说翻译,以实现C++的语法机制。主要来说有以下几种Semantics:
1) 明确的初始化操作(Explicit Initialization)
比如定义: X x0;
那么以下定义: X x1(x0); X x2 = x0; X x3 = X(x0); 都会被转化成: X x1,x2,x3; 在这里编译器并不会做这三个object的初始化,而是调用copy constructor进行初始化:
x1.X::X(x0); x2.X::X(x0); x3.X::X(x0);
2) 参数初始化(Argument Initialization)
C++ Standard ( Section 8.5)说,把一个class object 当做参数传递给一个函数或者把它作为一个函数的返回值时,相当于以下形式的初始化操作:
X xx = arg;其中xx是形式参数或者返回值,arg代表真正的参数值,因此类似于void foo(X x0);这种调用,将会使得local instance x0以memberwise的形式以实际参数为初始值进行初始化。
一般来说,编译器有两种做法:
a) introduce a temporary object
还是以上文的函数声明 void foo(X x0);
调用进入后,1、编译器生成一个temporary object:X _temp;
2、以实际参数xx 拷贝构造 这个temporary object:_temp.X::X(xx);
3、重新改写函数调用操作,foo(_temp);
4、最重要的一点就是修改参数调用方式为引用,否则如何工作又回到原点啦。。。void foo(X &x0);
b) 将参数直接以copy constructor建构到函数的堆栈上,这样也会有一个local object生成;当然在函数返回时该local object也会被destructed。
3) 返回值的初始化(Return Value Initialization)
当返回值是object时,这个object是如何返回的呢?cfront使用的是一个双阶段转化:
a) 首先加上一个额外的参数,是class object的reference,这个参数将放置通过copy constructor得来的返回值
b)在return之前安插一个copy constructor,以便将欲传回之的object当做上述新增参数的处置。
例如:X bar() { X xx; return xx;} 会被转化为:
void bar(X & _res) //这里安插了临时引用参数
{
X xx;
xx.X::X();
_res.X::X(xx); //这里安插了临时引用的拷贝构造函数
return;
}
现在编译器必须转化每个bar调用,以反映其新定义。例如X xx = bar(); ===> X xx; bar( xx );
而相应的 bar().memfunc(); //执行bar()所返回之X class object的member function
会被编译器转化为:
X temp0;
(bar(temp0),temp0).memfunc();
在返回值优化上,Optimization at the User Level or Optimization at the Compiler Level。在User Level, 设计者需要创建不同的constructor,这样object直接通过计算,而不需要copy constructor。这样做如果在非常注重效率的场合可能比较有意义,但是缺乏抽象。
在Compiler Level,现在广为认知的就是 Name Return Value(NRV)Optimization:
void bar(X & _res) //这里安插了临时引用参数
{
_res.X::X();
//直接操作_res
return;
}
也就是说,NRVO 省略了一次copy constructor的调用。但是如果copy constructor有side-effect的话,那么这个优化就会有问题。
书中提到,如果某个class 会有大量的object return value的情况,那么需要为该class define copy constructor,以触发NRV(或者叫RVO, Return Value Optimization)。但是,黄俊达先生认为:Lippman在p67最後一行所言『这个程式的第一个版本不能实施NRV最佳化,因为testclass缺少一个copyconstructor』,
此语错误。黄先生认为如果程式没有explicitcopyconstructor,编译器会自动为我们做出来(如为trivial,则直接bitwisecopy;如为nontrivial,则由编译器为我们合成出一个copyconstructor)。因此,有没有explicit copyconstructor并不影响NRV最佳化的实施。他认为NRV最佳化主要是 由编译器option来决定要不要实施。他并且做了一些实验,判断VC和gcc 都没有做到NRV最佳化,而其不做的理由不是因为技术上的困难,是为了避免造成「userdefinedcopyconstructor之副作用失效」--所谓副作用
是指,例如「在userdefinedcopyconstructor中做一个cout输出」之类这种「与memberwisecopy无关」的动作。
NRV优化还是很重要,比如下面的代码,如果没有NRV将会有三次copy 构造,二次析构:
Typeget(intI) { returnType(i); } Typet=get(1);
甚至有人认为user defined copy constructor会阻止NRV的优化。更多讨论可以参见:关于编译器对拷贝构造函数优化的问题再讨论
分享到:
相关推荐
2.3 程序转换语意学(Program Transformation Semantics) 明确的初始化操作(Explicit Initialization) 参数的初始化(Argument Initialization) 返回值的初始化(Return Value Initialization) 在使用者层面做...
2.3 程序转换语意学(Program Transformation Semantics) 明确的初始化操作(Explicit Initialization) 参数的初始化(Argument Initialization) 返回值的初始化(Return Value Initialization) 在使用者层面做...
2.3 程序转换语意学(Program Transformation Semantics) 明确的初始化操作(Explicit Initialization) 参数的初始化(Argument Initialization) 返回值的初始化(Return Value Initialization) 在使用者层面做...
德勤:Organization Transformation
思科PPT:Infrastructure Transformation - Nexus Technology Update
Networkers2009:BRKBBA-2010 - NG Mobile Networks: architectural transformation and evolution toward IP
大地测量坐标正反算转换,c++代码
本程序可用于空间坐标转换具有较高的精度。
homography perjective transformation 射影转换homography perjective transformation 射影转换homography perjective transformation 射影转换homography perjective transformation 射影转换homography ...
Inside the C++ Object Model focuses on the underlying mechanisms that support object-oriented programming within C++: constructor semantics, temporary generation, support for encapsulation, ...
Inside the C++ Object Model focuses on the underlying mechanisms that support object-oriented programming within C++: constructor semantics, temporary generation, support for encapsulation, ...
Beginning Python Visualization: Crafting Visual Transformation Scripts discusses turning many types of small data sources into useful visual data. And, you will learn Python as part of the bargain.
Inside the C++ Object Model focuses on the underlying mechanisms that support object-oriented programming within C++: constructor semantics, temporary generation, support for encapsulation, ...
数字转换局的网站 该网站于2018年11月存档。为确保您获得有关DTA的最新信息,。 技术 是。 依存关系 要在macOS上获得本地开发环境: # install homebrew ruby -e "$(curl -fsSL ...
Linear Transformation, 线性转换
坐标转换功能特别强大,不仅可以计算四六七参数,还可以将源坐标根据所求参数来求取目标坐标;坐标格式转换不仅实现了大地坐标、站心坐标、地固坐标之间...- CoordinateTransformation:软件源码,双击 *.sln 即可打开
浮动按钮与菜单切换的效果。...项目地址:https://github.com/konifar/fab-transformation 还有,就是导入我的demo时,别忘了修改SDK的版本:android:targetSdkVersion="",改成你的,我用的是19效果图:
rgb转lab代码matlab ...10deg转换的测试 该存储库包含用于重新格式化打印机反射率测量,计算LAB值并以正确格式存储LAB值的代码。 下载说明 这些命令将为您提供一份用于开发和测试目的的项目副本 $ git clone ...
普华永道:The GCC post-pandemic:Massive and fast transformation
快速傅里叶变换 FFT (Fast Fourier Transformation)介绍,包含java和C++实现。快速傅里叶变换 FFT (Fast Fourier Transformation)介绍,包含java和C++实现。快速傅里叶变换 FFT (Fast Fourier Transformation)介绍,...