免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: asker160
打印 上一主题 下一主题

[C++] 为什么把+++拆成++,+而不是+,++ [复制链接]

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
61 [报告]
发表于 2010-10-01 23:25 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
62 [报告]
发表于 2010-10-02 00:33 |只看该作者
绝对害人的语句,就不能用个括号吗?这样对大家都好。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
63 [报告]
发表于 2010-10-02 01:22 |只看该作者
j+++i这个表达式的,根据C标准 "the behavior is undefined"
也就是说这是个错误的程序,编译器给出任何结果都可以。

原因是:一个对象在两个顺序点(sequence point)之间只能读写一次。
j++产生一次写j,同时j+++i又有一次读j(并且读出的数据并不是用来改变j的值)这违反了C表达式的限制。

delimy 发表于 2010-10-01 17:04


确实跟标准说的不一致呀。

标准里的第一句话说,sequence point之间对象的值只能改变一次;第二句话说,对象被改变之前的值只能在“决定对象的终值”时引用。

标准里并没有说sequence point之间只能读写一次。

比如
  1. i = i +1;
复制代码
两个sequence point 之间读了一次 i 写了一次 i ,这个表达式肯定没事呀。。。。。。。

标准里说的第二句说非常不好理解,
Furthermore, the prior value shall be accessed only to determine the value to be stored.


根据http://c-faq.com/expr/seqpoints.html上面的解释:
And that's what the second sentence says: if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written


如果对象在full expression中会被改动(写入),则这个full expression中所有对该对象的引用一定是为了“确定这个对象的最终值”。 i = i +1 就是这种情况,i 会被写入, i + 1 里面引用 i 是为了确定 i 的最终值。 a[ i ] = i ++ 就违反了这条规则(虽然没有违反第一条),a [ i ] 中对 i 的引用不是为了“确定i的终值”。

我觉得还是标准里没说清楚,“the prior value”意思显然是“对象被改动之前的值”,但我怎么知道引用的是“对象被改动之前的值”还是“对象被改动之后的值”呢? 

按照标准的意思,a[ i ] 里引用的就是 i 的“the prior value”。那 i ++ + j 里有没有引用“the prior value”呢? ++i + j 有没有引用“the prior value”呢?( a = 1) + a 里有没有引用“the prior value”呢? *p++ = 0里有没有引用“the prior value”呢?a = b = 4有没有引用“the prior value”呢?

最终还是要看“the prior value”是怎么定义的。

在C语言的设计之初,并没有严格定义求值过程,像前置++、后置++这种东西只是抽象地规定“在操作之前加一”还是“在操作之后加一”,但何为“操作”呢?

规范则严谨地定义求值过程,引入sequence point的概念后就可以保证,++肯定会在下一个sequence point前生效,至于在什么时候生效则不能确定。像 a = i ++ 按C语言最初的语义,应该是可以根据优先级来确定求值行为的,自增在赋值之后发生。标准里却认定其为“未定义”行为。如果是a[k] = i ++情况又是怎么样呢?*p++ = 0 , c [ i ++ ] = 0这种经典语句是不是“未定义”呢?它们有没有引用了“the prior value“呢?结果又绕回什么是“the prior value”的问题上来了。不过这两种情况下,按照原始C语义里的优先级来解释,显然是引用的“the prior value”,那么根据标准,它们全是未定义的。

我觉得,第一条肯定不能违反,第二条还有商量的余地。规范里的第二条基本上把++,--操作符给废掉了。像 c [ i ++ ] = 0这样的表达式,虽然是未定义行为(如果理解正确的话),编译器显然可以确定会发生什么事。 i++ + j 亦是同理。这能不能看作约定俗成的规则呢? 全世界写编译器的人大概都不会因为这种”未定义“行为而中止编译过程吧,他们对”该发生什么事“的认识也应该是统一的吧。
===================================

PS:在CU上搜到这个帖子,http://bbs.chinaunix.net/viewthread.php?tid=310576,六年前就有人解释地这么清楚了。。。。。。

论坛徽章:
0
64 [报告]
发表于 2010-10-02 01:48 |只看该作者
确实跟标准说的不一致呀。

标准里的第一句话说,sequence point之间对象的值只能改变一次;第二句话 ...
tempname2 发表于 2010-10-02 01:22



    i = i +1;只存在一个序点而不是两个。

论坛徽章:
0
65 [报告]
发表于 2010-10-02 10:07 |只看该作者
回复 51# pmerofc

我好怕呀,现原形啦,人家都不屑于鄙视我啦!

能问出:
外部或static变量的生存期长于main()函数?
[C] 请教一个基础问题——数组名减1是否可以

这两个问题都需要问的人,还好意思说这里是幼儿园那个现原形不屑于鄙视。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
66 [报告]
发表于 2010-10-02 11:55 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
67 [报告]
发表于 2010-10-02 12:25 |只看该作者
i = i +1;只存在一个序点而不是两个。
ypyf3000 发表于 2010-10-02 01:48


i = i + 1 没有序点。前一个分号和后一个分号可以看做序点。。。。。。

论坛徽章:
0
68 [报告]
发表于 2010-10-02 12:36 |只看该作者
本帖最后由 ypyf3000 于 2010-10-02 12:41 编辑
i = i + 1 没有序点。前一个分号和后一个分号可以看做序点。。。。。。
tempname2 发表于 2010-10-02 12:25



    完整表达式的末尾存在一个序点。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
69 [报告]
发表于 2010-10-02 12:39 |只看该作者
完整表达式的末尾存在一个序点。
ypyf3000 发表于 2010-10-02 12:36


a full expression is an expression statement, or any other expression which is not a subexpression within any larger expression


full expression是表达式语句,或者是没有更上层表达式的表达式。

其实说得就是“最大的表达式”,后面那句话应该是针对if ,while里的条件说的。

论坛徽章:
0
70 [报告]
发表于 2010-10-02 12:41 |只看该作者
full expression是表达式语句,或者是没有更上层表达式的表达式。

其实说得就是“最大的表达式 ...
tempname2 发表于 2010-10-02 12:39



    顺便附带我从wiki上翻译的关于哪些地方存在序点的总结:
1.在&&(逻辑与),||(逻辑或)和逗号操作符的左操作数和右操作数的求值之间。
2. 在三元“问号”操作符的第一个操作数与第二个或者第三个操作数的求值之间。
3. 在一个完整表达式的末尾。这个范畴包括表达式语句(诸如赋值 a=b;),return语句,if,switch,while或者do-while等语句的条件表达式,还有for语句中的三个表达式。
4. 函数调用时,在进入函数体之前。
5. 函数返回时,在返回值被拷贝到调用上下文之后。
6. 在初始化式的末尾。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP