C_and_CPP 板


LINE

※ 引述《littleshan (我要加入剑道社!)》之铭言: : 推 holymars:RVO是因为Compiler会把return value当成参数传进function 10/20 13:02 : → holymars:里才会有的optimization吧..如果函式本身inline 10/20 13:03 : → holymars:就不用把return value放在参数列上,自然也不会进行 10/20 13:03 : → holymars:RVO啊.. 10/20 13:03 : RVO 牵涉的不只是 implementation detail : 它也会影响到语意 : 因为它是直接「消除」掉 copy-constructor/assignment : 即使这个 copy-constructor 具有 side effect 也是一样会被省略 : 但 inline function 是不能影响语意的 : compiler 不能因为 inline function 就自动省略该有的 constructor/assignment : 除非说 copy-constructor/assignment 是 compiler 自己产生所以它知道内容 RVO和NRVO是不一样的 RVO也是不能影响语意的 根据inside the C++ object model的说法 最先提出RVO的Jonathan Shopiro,是因为Compiler会把return value传进参数列 并且在return之前隐含产生一个copy constructor RVO是为了省掉compiler自动产生的这个copy constructor所发展的技术 它省掉的是compiler产生的,所以并不影响语意 书中举例是像这样: Foo bar() { Foo f; //中间对f做了某些操作 return f; } 这样的code会被compiler转化成 void bar(Foo& __ret) { Foo f; //中间对f做了某些操作 __ret.Foo::Foo(f); // 在这里呼叫copy ctor return; } Jonathan Shopiro想省掉那个compiler自动产生的copy ctor 所以希望return value在函式中匿名存在 把所有的操作移到另一个constructor去进行 Foo bar() { return Foo(bulabula...); // 这是个「计算用的constructor」,用来取代前述的「对f做了某些操作」 } 这样Compiler就不会去呼叫那个隐含的Copy constructor 而是会直接在return的时侯调用那个「计算用」的copy ctor 以上是RVO NRVO就像原文所说的 即使return value不是匿名,而是一个具名(Named)的变数 一样透过Compiler优化把那个具名的变数取代成Compiler 传进去的__ret 这样它不止省掉了那个原本会隐式产生的copy ctor 连带的copy ctor的side effect也从local variable转移到了return value上面 而且这个side effect有可能不只是printf("xxxx\n")而已 举下面的例子来说 inline Foo bar(const Foo& f) { Foo tmp = f; // copy constructor return tmp; } 使用者原本预期 Foo tmp = f; 这行copy-initialization会对tmp产生某些side effect 但是不会影响到return回去的值的行为 这听起来很吊诡 但是是有可能的 因为Compiler调用的 __ret.Foo::Foo(tmp); 是direct-initialization 虽然在大多数情况下这两种initilzation会invoke同样的constructor Compiler帮你把原本预期对tmp做的copy-initialization 变成对__ret做了 上面是解释RVO和NRV的不同 然後来看看原本的问题 : List Test::GetList() : { : return m_oList; : } : : List oList = oTest.GetList(); 嗯..其实这个函式既没有动用到RVO,也没有动用到NRV 我用VC8.1 compile了一个完全不optimize的asm 就算是完全没有optimize的版本 也只在function里面做了一次copy ctor (compiler预设产生的那个) 结果Debug版的pseudo code长得像这样: (函数名称是打乱过的,我用__GetList代替) void __GetList(List& oTest, List& oList) { //前面一堆stack处理 oList.List::List(oTest.m_oList); //後面一堆stack处理 } List oTest; List oList; __GetList(oTest, oList) 也就是说 真正被省掉的东西是function「外面」的那个copy constructor 另外 如果写成 : List Test::GetList() : { : return m_oList; : } : : List oList; : oList = oTest.GetList(); 就会出现copy ctor -> copy assignment -> copy ctor这样的呼叫顺序 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.32.15.163
1F:→ holymars:最後那个copy ctor是因为copy assignment传回的不是 10/20 16:07
2F:→ holymars:List&而是List 所以又产生一个隐形的copy ctor.. 10/20 16:07







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Tech_Job站内搜寻

TOP