作者cgcheng (..)
看板C_and_CPP
标题Re: 十三诫增修--08:++i/i++和--i/i--顺序影响结果
时间Thu Jun 9 22:48:41 2016
※ 引述《wtchen (没有存在感的人)》之铭言:
: 这篇有争议,乾脆直接重写,看大家认为如何
: (尤其希望C++的高手能补充或指正,特别是multithreading的部份)
: ==============================================================
: 08. ++i/i++ 和 --i/i-- 的结果跟你怎麽用有关
: ++i/i++ 和--i/i-- 的问题几乎每个月都会出现,所以特别强调。
抱歉,觉得用推文空间有点窄,乾脆回文比较 free
multithread 的状况也是蛮多的,虽然我程式没有你们那麽厉害
不过基本上如果两个 thread 同时执行到这行: ++i,他的结果就像
你们讲的无法预期
multihread 有可能跑在只有一个 core cpu 的状况下,这时候两个
thread 跑 ++i 最後就真的是 i+=2,如果是单 core 但却 enable
hyperthread 的话,这部分我有点点忘了,不过印象中依然会是
i+=2,因为物理上还是单核,这部分可以给了解详情的人补充,
hyperthread 我不会,讲的不一定对
不过现在都是多核啦,所以结果是无法预期的,会讲到多核跟单核
的原因是在不同的机器上确实有机会碰到一台老是会有 race conditon
另外一台老旧的机器却没有问题的状况
c++ 的最新 atomic 运算表达方式标准我不确定长得如何,因为印象
中这部分在过去一直有进步,不过应该 google 是找得到才对,再来跟
使用的 compiler 以及版本也有关系,使用前需要详阅公开说明书
anyway,如果一个变数 i 被宣告成 static 或者什麽样的形式,使得
变数 i 有可能会让两个以上的 thread concurrent 去 access 时,
用 ++ 或者 -- 是不稳当的,要嘛就是 lock,要嘛就必须确定是 atomic
operation
以上是个人的经验,我不是很谨慎的人所以懒得再去翻找资料比对,所以
我相信会有高手出来指正或者补充的更多,能抛砖引玉我觉得也不错。只
是刚好看到版主讲到 multithread 就手痒痒献丑
只不过我觉得单纯 c/c++ 的讨论就够啦,又要再引进 multi-thread 的话
我觉得议题有点点大,因为这又可以再牵扯的更多更多,版主以及我看另外
一位网友讲的东西就已经很 detail 也很专业,在更扩及下去个人是觉得有
些些 over,拙见拙文参考看看,如果有说错先 say sorry,很怕被冠上误人
子弟的罪。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 223.136.110.41
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1465483724.A.84A.html
※ 编辑: cgcheng (223.136.110.41), 06/09/2016 22:53:56
1F:→ Caesar08: 讨论这部分的时候不会讨论到multi thread,因为multi th 06/09 22:58
2F:→ Caesar08: read本来就要自己sync 06/09 22:58
3F:推 wtchen: 因为C++Standard有multithread的东西,想请问Standard 06/09 23:03
4F:→ wtchen: 对这方面到底是如何规定的? 06/09 23:03
5F:→ cgcheng: 因为版主问了,所以我特地稍微查了一下c++11关於多线程 06/09 23:23
6F:→ cgcheng: 看起来是把对多线程的支援度提高,实际使用上仍然需要观 06/09 23:24
7F:→ cgcheng: 念 06/09 23:26
8F:推 wtchen: 感谢,因为我大部份都用C所以C++比较不熟 06/09 23:27
9F:→ wtchen: 既然不会影响我就放心了 06/09 23:28
10F:→ cgcheng: 不过我刚重看了一下讨论串,caesar08你有参与讨论? 06/09 23:28
11F:→ cgcheng: wtchen看得出你很仔细谨慎,我个人是颇欣赏,我所讲的只 06/09 23:31
12F:→ cgcheng: 是提醒加上手贱,never mind 06/09 23:32
13F:→ wtchen: 给新手看的东西要很小心,不要造成太大的误解让新手一开始 06/09 23:34
14F:→ wtchen: 观念错误,所以谨慎为上。 06/09 23:34
15F:→ cgcheng: 啧啧,所以一开始我其实不是很想发文,因为要很谨慎 06/09 23:35
16F:→ wtchen: 讨论的时候无所谓啦,板工发的置底文就另当别论了 XD 06/09 23:36
17F:→ Caesar08: no。我只是要说,不需要考虑到multi thread的情况 06/09 23:36
18F:→ cgcheng: 不过那个什麽逗号是分隔号还是运算元这个新人应该看不懂 06/09 23:36
19F:→ cgcheng: caesar08,y..我讲同件事...但总觉得感觉哪边怪怪的 06/09 23:38
20F:推 wtchen: ,运算符那边要是没人提我也不知道 XD 06/09 23:45
21F:→ wtchen: 不过,分隔号不算sequence point应该是必备常识 06/09 23:46
22F:→ cgcheng: 常识?!其实在很久前我并不知道.後来就算知道了但还真的没 06/09 23:48
23F:→ cgcheng: 遇到让我有机会去管这个差别的时刻 06/09 23:49
24F:→ cgcheng: 好比有一条好像是说不要overload逗号,实际上就是不会有 06/09 23:52
25F:→ cgcheng: 人这样搞 06/09 23:52
26F:推 wtchen: 例如F(a(&x), b(&x)),如果a跟b都会改变该引数指标指向 06/09 23:52
27F:→ wtchen: 的变数(x),那结果就会看a先执行还是b先执行 06/09 23:53
28F:→ wtchen: 当然会这样搞的应该很少.... 06/09 23:54
29F:→ cgcheng: oh,boost好像有这样干,那那那当我没常识好了 06/09 23:54
30F:→ cgcheng: func里面再有func,好像也是,勾起我一点点回忆..不过很少 06/09 23:56
31F:→ cgcheng: 倒是真的 06/09 23:56
32F:推 wtchen: 因为C有aliasing,如果观念不太对写出的code会很奇怪 06/09 23:58
33F:→ cgcheng: alias是啥 06/09 23:59
34F:→ wtchen: 虽然可以strict aliasing,可是有些高手也会用aliasing 06/10 00:00
35F:→ wtchen: 做些有的没的特技。 06/10 00:00
37F:推 Frozenmouse: 原本非题所涵盖的范围比现在的广很多,改这样感觉变 06/10 00:08
38F:→ Frozenmouse: 成是只针对 ++ -- 而已了… 06/10 00:08
39F:→ Frozenmouse: 原本非题→原本题目 06/10 00:08
40F:推 Hazukashiine: 其实我原本想到比较好的题目是: 06/10 00:12
41F:→ Hazukashiine: 不要在两个顺序点之间,对同一个变数赋值 06/10 00:12
42F:→ cgcheng: wtchen谢谢,我看了一下觉得好像开-Wall就有机会避免 06/10 00:13
43F:→ cgcheng: Hazukashiine的题目不错 06/10 00:14
44F:推 Hazukashiine: 呜呜被切掉了QQ ...,对同一个变数赋值两次以上 06/10 00:16
45F:→ Hazukashiine: 但是我觉得啊~越精确的解释,新手真的越容易理解吗 06/10 00:17
46F:→ cgcheng: 当然不会理解 06/10 00:18
47F:→ Hazukashiine: 只是要避免写出一些奇怪代码而要去理解顺序点是什麽 06/10 00:19
48F:→ cgcheng: 只会让他更乱而已 :) 06/10 00:19
49F:→ cgcheng: 其实我反而好奇你不跟新人讲,他就真的会写出奇怪的东西? 06/10 00:20
50F:→ cgcheng: 忘了问,wtchen所说的alias是指point来point去吗? 06/10 00:23
51F:→ Hazukashiine: 也许会。因为我就做过这种事,在我是新手的时候 www 06/10 00:24
52F:→ cgcheng: 回文还挺累的,小弟要先告退了..也许不会再回来看这串 06/10 00:24
53F:推 Frozenmouse: 第一次学++ --兴奋到写出奇怪的东西也是有可能的XD 06/10 00:26
54F:→ cgcheng: Hazukashiine,really?看来要学好程式真的很难 06/10 00:26
55F:→ Frozenmouse: 更不用说会有教授教这个… 06/10 00:27
56F:→ cgcheng: 不才小弟第一个学lang的叫做quick basic QQ 06/10 00:28
57F:→ cgcheng: 我不是资工的,不过一般计算机概论我肯定教授不会教这个XD 06/10 00:29
58F:推 wtchen: Hazukashiine的题目我也想过,可是要跟新手解释顺序点 06/10 00:29
59F:→ wtchen: 好困难阿....而且++/--算是月经题了 06/10 00:30
60F:→ Hazukashiine: 对啊,想到就觉得会适得其反 XDDD 06/10 00:30
61F:→ wtchen: alaising就是一个函式两个以上pointer参数是同一个这样... 06/10 00:31
62F:→ Hazukashiine: 所以我就想说用 在一个无顺序点的表示式中... 06/10 00:31
63F:→ wtchen: 一般人不会这样搞不过compiler预设就是假设真的有人这样写 06/10 00:31
64F:→ Hazukashiine: 一是逻辑等价的,二是也许看的人会直接无视顺序点XD 06/10 00:32
65F:→ cgcheng: parameter同个pointer?有需要这样子用阿? 06/10 00:32
66F:→ wtchen: 现在大学到底教不教顺序点?如果有教的话怎麽老是有++/-- 06/10 00:32
67F:→ wtchen: 的问题出现? 06/10 00:33
68F:→ Hazukashiine: 不教,因为这是实作的细节,不是程式语言理论基础 06/10 00:33
69F:→ Hazukashiine: 遇到的人,自己想办法除错啦,自己就会发现了吧应该 06/10 00:34
70F:推 wtchen: cgcheng大不看这串OK,要回来看文发文就好.... 06/10 00:34
71F:→ cgcheng: 我怎麽觉得可以解读为++/--学好就是一个破处的成长开始XD 06/10 00:35
72F:→ Hazukashiine: 老师也会尽可能不出那种自己为是要背优先级的烂题目 06/10 00:35
73F:→ Hazukashiine: 以 06/10 00:35
74F:→ wtchen: 不过因为C++的作法跟C又有不同,所以原题目不太合适 06/10 00:36
75F:→ wtchen: C++可以允许 ++++i这种写法 06/10 00:37
76F:→ wtchen: 有人有更好的意见欢迎提出,集思广益! 06/10 00:37
77F:→ Hazukashiine: 不然就扩展题目的范围:不要做出语言未定义的性为? 06/10 00:38
78F:→ cgcheng: ++++i因为可能还要考虑operator overload吧? 06/10 00:38
79F:→ Hazukashiine: 行 06/10 00:38
80F:→ Hazukashiine: ++i 在 C++ 是 lvalue 而 C 是 rvalue 06/10 00:39
81F:→ cgcheng: 你们讨论的本来就到了实作上的细节,不过实际上到底要不要 06/10 00:39
82F:→ cgcheng: 管这些都还很难说 06/10 00:40
83F:→ wtchen: 不要做出语言未定义的行为->未定义行为多到数不清~~ 06/10 00:41
84F:→ Hazukashiine: 对啊 XDDD 没错啊 但是可以举几个常见会犯的例子 06/10 00:41
85F:→ cgcheng: 我这个新手只会觉得哪来这麽多毛 :~~ 06/10 00:42
86F:→ wtchen: 所以我尽可能举例说明....但是C跟C++分歧已经越来越大 06/10 00:42
87F:→ Hazukashiine: 不过这会让它与前面的东西重叠,修改字串常量就是UB 06/10 00:43
88F:→ wtchen: 要兼顾其实有点复杂,加上很多老师把C++当C教 06/10 00:43
89F:→ cgcheng: 好吧,到这很明显crazy,只是路过,很谢谢你们陪我 XD 06/10 00:43
90F:→ wtchen: C++都快出到17了还在用C的语法... 06/10 00:44
91F:→ Hazukashiine: 不然就分成新手与进阶两种不同的内容(误 06/10 00:45
92F:→ wtchen: 所以我才想说针对++/--就好,就如cgcheng说的,搞懂 06/10 00:45
93F:→ wtchen: 就很不容易了 06/10 00:45
94F:推 wtchen: 标题改了一下 06/10 15:28
95F:→ wtchen: "++i/i++/--i/i--/f(&i)哪个先执行跟顺序有关" 06/10 15:28
96F:→ wtchen: 不知这样好不好?原标题因为真的不太正确所以不能用 06/10 15:29
97F:→ Hazukashiine: 没有说不好,但是实在这样下去越来越复杂也是不妥QQ 06/10 16:33
98F:推 wtchen: 我是觉得正确最重要,已经尽可能简化了 06/10 16:50
※ 编辑: cgcheng (223.136.110.41), 06/11/2016 03:26:36
99F:推 locklose: 朝圣推 06/29 16:01