C_and_CPP 板


LINE

开发平台(Platform): (Ex: Win10, Linux, ...) win10 1803 WSL@Debian 编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出) g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 c++11 额外使用到的函数库(Library Used): (Ex: OpenGL, ...) <iostream> 问题(Question): 有两个相似的case,烦请参照外部连结阅读;编译以及执行的选项如下 $ g++ -c my_PTT_post.cc --std=c++11 -O0 -Wall -fno-elide-constructors $ g++ -o test my_PTT_post.o $ ./test 想要使用这些编译选项以免除NRVO/RVO,方便观察ctor呼叫行为 两个case的差异仅在於 // case1,pass by value myClass g (myClass other); // case2,pass by rvalue reference myClass g (myClass&& other); 以下是case1的结果以及个人的理解 (myClass g( myClass other ); ) ctor // ctor without parameter inside function f mv ctor // returned object of f steal the rvalue created by ctor mv ctor // obj1 steal RHS of "=" sign; RHS is a rvalue expression ctor // ctor without parameter inside function f inside function g mv ctor // returned object of f steal the rvalue created by ctor mv ctor // parameter of g steal what returned by f, which is rvalue inside g // now inside function g mv ctor // returned object of g steal the glvalue in g, which is at the end of its lifespan mv ctor // obj2 steal RHS of "=" sign, which is a rvalue expression 以下是case2的结果以及个人的理解 (myClass g( myClass&& other ); ) ctor // ctor without parameter inside function f mv ctor // returned object of f steal the rvalue created by ctor mv ctor // obj1 steal RHS of "=" sign; RHS is a rvalue expression ctor // ctor without parameter inside function f inside function g mv ctor // returned object of f steal the rvalue created by ctor inside g // g takes rvalue reference, so we step into g directly cp ctor // returned object of g is a copy of the rvalue reference in g mv ctor // obj2 steal RHS of "=" sign; RHS being a rvalue expression 不懂的地方有2: 1. operator =以及obj1/obj2原本自己的ctor怎麽都没有被呼叫呢? 还是case1、case2当中(应该要)呼叫ctor without parameter以及operator =的写法 myClass obj1 = f(); myClass obj2 = g(f()); 实际上等同没有用到ctor w/o parameter、operator =,仅用到mv/cp ctor myClass obj1(f()); myClass obj2(g(f())); 的这个写法呢? 2. case2当中,最後有一个copy ctor被呼叫了 这个copy ctor应该是为了把g吃进来的rvalue reference return回外面 但是为甚麽需要用到copy ctor呢? 除非使用者故意用了std::move()把expression转成rvalue丢进g 不然这个reference所代表的东西应该会是马上就要过期的rvalue 一般情况下如同case1呼叫mv ctor可以省一些资源吧? 喂入的资料(Input): nope 预期的正确结果(Expected Output): 如问题描述 错误结果(Wrong Output): 应该是我有哪里搞错了QQ 程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档) case1: https://godbolt.org/g/hBX1yw case2: https://godbolt.org/g/nXqyYc 补充说明(Supplement): 烦请各位指点 m(_ _)m --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.233.88.219
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1529748654.A.1FC.html
1F:→ bluesoul: 1你的理解是对的 06/23 18:50
2F:嘘 KanzakiHAria: 缩写看得很不舒服 Constructor就打完整 06/23 20:25
3F:→ KanzakiHAria: 一个物件实体化第一次的=不会使用operator= 06/23 20:26
4F:→ KanzakiHAria: 所以第一次=会呼叫constructor 06/23 20:26
5F:→ KanzakiHAria: move可能慢的原因为复制成本太低 06/23 20:27
6F:→ KanzakiHAria: std::move是一个function 所以还是会有离开回来 06/23 20:28
7F:→ KanzakiHAria: 例如int 型态还特地调用move就会造成过多的搬移成本 06/23 20:28
8F:→ KanzakiHAria: move最值得使用的情境为:当一个需要deep copy的物 06/23 20:29
9F:→ KanzakiHAria: 件要用来初始化别人,这时候move就不需要copy 06/23 20:30
10F:→ KanzakiHAria: 但是如果这个东西之後还要继续用就无法使用move 06/23 20:30
11F:→ KanzakiHAria: 那只好回到使用copy 06/23 20:30
12F:→ KanzakiHAria: 简单说可以想像类似搬进去function的scope 06/23 20:32
13F:→ KanzakiHAria: 离开function 的时候这个东西会destruct 06/23 20:32
14F:推 legendmtg: ctor是很惯用的缩写吧 06/23 20:37
15F:→ chchwy: 并没有什麽实体化第一次不呼叫operator=的规则 06/23 20:41
16F:→ chchwy: 那是因为编译器开了RVO 你把RVO关掉就可以看见正确行为 06/23 20:42
17F:→ chchwy: 然後ctor/dtor根本就超常见 06/23 20:42
我以为已经关掉RVO了耶 参照 https://goo.gl/3D5p3x 有在编译选项加 -fno-elide-constructors 根据内文贴的code连结,比较了一下问题一提到的两种写法产生的组语 (编译选项同内文所提) 发现main里面的组语一模一样 因此这部份结果应该如蓝魂、神崎亚莉亚所提 compiler对於两种写法的处理方式是一样的 这里( https://stackoverflow.com/a/8777310 )的回答也认为compiler是这样处理的 不过还是不太懂问题二的部份 甚麽情况下编译器会决定用mv ctor来把东西传回外界 又是甚麽时候会决定优先采用cp ctor啊? ※ 编辑: a58524andy (36.233.88.219), 06/23/2018 22:06:24
18F:→ Feis: 名字 06/24 01:09
19F:推 BlazarArc: ctor很常见的缩写 06/24 01:19
20F:→ Feis: case 2. reference (cp), std::move (mv) 06/24 01:25
21F:推 steve1012: ctor 很ok的 06/24 03:46
22F:推 KanzakiHAria: 你在讲什麽?constructor的return是void哪有甚麽回传 06/24 06:20
23F:→ KanzakiHAria: function return都是rvalue 建构子也是 06/24 06:27
24F:→ KanzakiHAria: 我终於看懂你的问题了...... 06/24 06:45
25F:→ KanzakiHAria: 因为你的g不是回传reference type 06/24 06:45
26F:→ KanzakiHAria: 当然不会动到reference的constructor阿...... 06/24 06:46
27F:→ KanzakiHAria: 你的问题是连最基本的三种呼叫和回传都没搞懂 06/24 06:48
28F:→ KanzakiHAria: call by value, call by address,call by reference 06/24 06:48
29F:→ firose: 这问题 (https://bit.ly/2K5zUvu) 也有人问但没答案 06/24 07:04
30F:→ firose: 感觉他是 xvalue 应该能安全 move 才对 06/24 07:06
31F:推 KanzakiHAria: 因为在function内scope是lvalue reference 06/24 07:34
32F:→ KanzakiHAria: 也就是原PO的22行还要使用move才会cast回rvalue ref 06/24 07:37
33F:→ KanzakiHAria: erence 06/24 07:37
34F:→ firose: 问题是 case1 也是 lvalue 就可以 move 06/24 07:53
35F:推 KanzakiHAria: 所以是RVO关不掉? 06/24 07:58
36F:→ KanzakiHAria: RVO是c++11的standard 06/24 07:59
37F:→ KanzakiHAria: 名称是copy elision 06/24 08:00
38F:推 KanzakiHAria: 我把原PO的code改了一下 http://cpp.sh/4u437 06/24 08:45
39F:→ KanzakiHAria: 28行VS报错内容 06/24 08:46
40F:→ KanzakiHAria: 'return': cannot convert from 'myClass' to 'myCl 06/24 08:46
41F:→ KanzakiHAria: ass &&' 06/24 08:46
42F:→ KanzakiHAria: Clang报错内容 06/24 08:47
43F:→ KanzakiHAria: rvalue reference to type 'myClass' cannot bind t 06/24 08:47
44F:→ KanzakiHAria: o lvalue of type 'myClass' 06/24 08:47
45F:→ loveflames: return语句为非静态物件名称时,才以move取代copy,rv 06/24 10:40
46F:→ loveflames: alue ref并不是一个物件 06/24 10:40
47F:→ loveflames: 还有楼上那个错误讯息是因为decltype(auto)是推导出my 06/24 11:06
48F:→ loveflames: Class && 06/24 11:06
49F:→ loveflames: 不是你以为的myClass 06/24 11:06
50F:→ loveflames: 你可以把h函数想成这样 06/24 11:07
51F:→ loveflames: decltype(auto) tmp = other; 06/24 11:08
感谢推文各位 稍微整理对於回答二的意见如下 参考firose的连结 在case2中 // myClass g (myClass&& other); 在g函式里面 吾人不能直接把"other"这个expression当成rvalue看待 否则"other"这个expression在g呼叫其他函式的时候容易被玩坏 同时参考n3337 https://goo.gl/SXrM4E ch.5 pg.97 note.6 "an expression is an xvalue if it is [...] a cast to rvalue reference to object type," "other"这个expression在g里面应该被当成一个xvalue使用 至於这个xvalue expression传回时的行为则如loveflames所提 实际上"other"还是一个reference而不是一个non-static object 因此采用了cp ctor而没有采用mv ctor 如果有错的话烦请不吝指正@@ ※ 编辑: a58524andy (36.233.88.219), 06/24/2018 16:52:45







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灯, 水草

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

TOP