i + i++ ;是undefined behavior的表达式语句吗?理由!

mu_yang 2009-08-01 07:21:38
结论无关紧要,
核心是理由。
...全文
811 121 打赏 收藏 转发到动态 举报
写回复
用AI写文章
121 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2009-08-03
  • 打赏
  • 举报
回复
囧,讲C、C++标准不完善的书已经够多了,就别再扯远了。
mu_yang 2009-08-03
  • 打赏
  • 举报
回复
都快搞成哲学问题了


1.“完善”的定义?
2.我们现在讨论问题只能是在标准的框架之下
3.标准有错误或不合理或不合逻辑不是绝对不可能的,但一定要有根据的说
泛泛地谈标准的完善与不完善,没有意义
飞天御剑流 2009-08-03
  • 打赏
  • 举报
回复
标准不是不能完善,而是不可能完善,或者说不可能绝对完善,无论计算机语言标准也好,现实中的法律也好,都不可能有绝对完善。

我们这个宇宙是相对的,不是绝对的,完善这个词是相对的,当我们说一个东西是否完善的时候,只是相对于某个参照物而言,而参照物可以有无限多个.........

说白了,就是我们可以要求保准在某方面做得完善,但不可能要求它方方面面都做得完善。
qepjatdwj 2009-08-02
  • 打赏
  • 举报
回复
原来C这么博大精深!
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
我很欣赏#24楼认真明晰概念的这种态度
也感谢#24对unspecified behavior、
implemantation defined、
undefined behavior
这三个概念的阐述

我很想问继续请教
既然unspecified behavior“意思是标准提出两种或多种处理方法,编译器可以从中选择一种”
那么您认为标准对 i + i++ ; 提出了哪些处理方法?

mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 65 楼 baihacker 的回复:]
命令式,函数式,逻辑式,脚本式.
几种并不是独立的,前三种是从本身范式来看的,脚本是从应用角度来看的.
而且,在函数式中也可以有命令式,在命令式中也可以有函数式.
[/Quote]
多谢指教
以后再仔细研究
baihacker 2009-08-02
  • 打赏
  • 举报
回复
命令式,函数式,逻辑式,脚本式.
几种并不是独立的,前三种是从本身范式来看的,脚本是从应用角度来看的.
而且,在函数式中也可以有命令式,在命令式中也可以有函数式.
baihacker 2009-08-02
  • 打赏
  • 举报
回复
...我是在和中缀类比...

把()里面的内容看作运算符,把函数名看作操作数,就是后缀式,
把函数名看作运算符,把()里面的看作操作数,就是前缀式了.

从描述这个表达式的意思来讲,两者没有本质区别,因为可以都归为后缀表达式,何必再多事.
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 52 楼 baihacker 的回复:]
问题的源头在命令式语言:用变量暂时保存一个状态,所以就有了这种副作用.
[/Quote]
不太理解
能否详细说说
除了“命令式语言”
还有什么“式”?
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 61 楼 baihacker 的回复:]
中缀,因为这个运算符在两个操作数中间...
+ a b 前
a + b 中
a b + 后
a ? b : c 中

更多操作数的运算,比如是X个操作数的,那么用中缀就要用X-1个符号,很不方便,也不直观,于是就用前缀式:
function(a,b,c,d,e);
函数调用,可以看作一种前缀式.
[/Quote]
我的印象
C语言恰恰把函数调用归为了Postfix operators
baihacker 2009-08-02
  • 打赏
  • 举报
回复
中缀,因为这个运算符在两个操作数中间...
+ a b 前
a + b 中
a b + 后
a ? b : c 中

更多操作数的运算,比如是X个操作数的,那么用中缀就要用X-1个符号,很不方便,也不直观,于是就用前缀式:
function(a,b,c,d,e);
函数调用,可以看作一种前缀式.
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 baihacker 的回复:]
写成a+b的形式的时候已经是中缀了.
在C中是有初等表达式,后缀表达式的..
然后中缀表达式由于优先级的原因,被分为
乘法性质表达式,加法性质表达式,位移性质表达式,关系性质表达式,等价性质表达式,and,xor,or...一大堆
这样是有利于语法的形式化的.
[/Quote]
那“逗号”是什么缀?
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 arong1234 的回复:]
……但是意义在哪,谁也不知道。
……
[/Quote]
你不知道
不能说“谁也不知道”

麻烦不知道这问题意义的网友
先正式指出自己不知道
麻烦认为该问题“无意义”的网友
给出象样的、值得反驳或商榷的理由
或者另外发帖讨论
在下一定参加

飞天御剑流 2009-08-02
  • 打赏
  • 举报
回复
i + i++ ;是undefined behavior的表达式语句吗?理由!
--------------------------------------------------------
单看楼主这句话,楼主就有一个概念上的错误。


求值顺序不是undefined behavior,而是unspecified,unspecified跟undefined是两码事。


在标准中,有三种行为方式的规定:

一:unspecified behavior,未指定行为。意思是标准提出两种或多种处理方法,编译器可以从中选择一种;

二:implemantation defined,实现定义行为。基本意思跟unspecified一样,也是编译器从中选择一种,但是,编译器需要在说明文档中指出此编译器采用了哪一种方法,而unspecified不需要告诉使用者。

三:就是undefined behavior了,未定义行为。意思是标准对于此施加于错误的程序结构或者错误数据上的行为,不作任何规定。编译器可以自行处理。

上述三种行为标准在前部的概念解释中都有介绍,限于编幅不在这里摘录了,可以自行查阅。

求值顺序属于unspeciafied行为,不是undefined行为。编译器对于运算符的左或右操作数,可以选择其中一种计算顺序,并且不需要在文档中说明。

这个问题楼主既然发在c版,就应该用c标准去解释。摘录c99的原文,c90基本一样。

Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.

就是除了函数调用、逻辑与和或、条件表达式、逗号表达式外,其它表达式的计算顺序与副作用的产生都是未指定的。

根据这条规定,i + i++;就是未指定行为。对于i与i++的计算顺序,不同编译器会有所不同。


还需要注意,对于副作用何时产生,标准只保证在达到顺序点时,副作用被完全求值,但不保证达到顺序点前,副作用何时被求值。

正因为如此,在楼主贴出来的这种表达式里,别以为那个是后增量,就必定会先使用后一个i,再自加,不一定的!!此表达式语句的分号处有一个顺序点,只保证在达到此顺序点时i自加一次,但何时i进行自加,各个编译器会有所不同,也因此各种编译器可能呈现不同的结果。

特别指出的是,由于国内很多书(也包括国外有些书),并没有对求值顺序与结合性作一个完整的表述,造成不少人在这些问题上互相混淆,特别是那些基础不牢的人,容易把求值顺序、优先级、结合性几个概念理解得一蹋糊涂!
baihacker 2009-08-02
  • 打赏
  • 举报
回复
写成a+b的形式的时候已经是中缀了.
在C中是有初等表达式,后缀表达式的..
然后中缀表达式由于优先级的原因,被分为
乘法性质表达式,加法性质表达式,位移性质表达式,关系性质表达式,等价性质表达式,and,xor,or...一大堆
这样是有利于语法的形式化的.
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 51 楼 arong1234 的回复:]
其实无论是楼主还是热心回答问题的大众,只要能说出“回答好这个问题后的好处在哪”,就一切ok了。
[/Quote]
我来论坛是为了讨论问题的
不是来向小学生传教的
当然有初学者有疑惑需要帮助的时候是另一回事情
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 49 楼 baihacker 的回复:]
一个是单目运算符,另一个是双目的...

由于中缀的表达式形式在有若干个双目运算符的时候,先计算哪个是不确定的,所以在不同的运算符中出现了优先级,在相同的运算符中出现了结合性,以便于确定计算顺序.

在单目运算中也有,不过单目是针对一个操作数的,
后缀的单目运算高于前缀式的:如*p++;
在两个前缀的时候离表达式近的先:如*++p;
在两个后缀的时候也是离表达式近的先:如p++[1],pp[1][2];

i + i++;
中+是双目的
++是单目的

++和+木有竞争关系

而a + b * c;
这两个双目会有竞争关系的.
[/Quote]
几乎完全不能同意
不过话题可能越扯越远了
我就不多说了
只讲一句
“中缀”不是C的概念
我倾向于只用C的概念讨论C
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 arong1234 的回复:]
我所谓的二义性,是指那种只要一看就知道它肯定不可能产生二义性的直观二义性
[/Quote]
呵呵
压根不需要对语言的理解
只需要“一看”
佩服
happypeter2008 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 50 楼 arong1234 的回复:]
我所谓的二义性,是指那种只要一看就知道它肯定不可能产生二义性的直观二义性,而不是你这种通过“专家”证明它没有二义性的东西。绝大多数C++程序员恐怕都不会研究这么深入,能够引经据典来证明一个东西,在这种情况下,你这种需要证明的二义性只能让那些不知道的人吃苦。而从上面那位盛赞“C博大精深”的人来看,还是有很多人被你引导到以为这很重要的方向去的。

其实很简单
a=i + i++;

a= i + i;
i++
这两种表达式谁更没有让人糊涂的东西,不是非常一目了然么?有什么理由我们应该去研究前者而不使用后者。
引用 48 楼 mu_yang 的回复:
引用 43 楼 arong1234 的回复:
写软件的正确方法是使用最简单的没有二义性的且容易阅读、维护的表达式,从而降低成本。即使有人证明这个表达式是安全的,你能在哪儿用?项目组中只要有一个对此有疑问,你的表达式都会产生非常不好的后果。


“写软件的正确方法是使用最简单的没有二义性的且容易阅读、维护的表达式”
这很对
但前提是知道什么样的有“二义性”、什么样的没有“二义性”
难道不是吗



[/Quote]
同意
mu_yang 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 arong1234 的回复:]
只要你能证明这种问题的实际意义,我相信谁也不能指责你无聊或者无知。关键研究这个问题的人从来不正面证明自己的研究的意义何在,顶多说这是“C++知识”,弄清楚有意义,但是意义在哪,谁也不知道。
引用 42 楼 mu_yang 的回复:
引用 38 楼 arong1234 的回复:
什么时候大家才能摆脱“不管它有没有用,只要是‘知识’我就要研究”和“有麻烦解决麻烦,没有麻烦制造麻烦我也要解决”的怪圈有多好?研究这种无聊幼稚的问题,除了耽误时间,实在想不出有什么用处。

恐怕是狂了一点
不能说你不理解问题的意义
就都是“幼稚无聊”
而你知道的问题才不是“幼稚无聊”吧

[/Quote]
相信有识之士能理解这问题的意义
至于我提出它
自然是认为有意义
但我没有义务向不知道问题意义的人科普
至于你说没意义或你认为没意义
我没看到你拿出了象样的理由
加载更多回复(101)

69,337

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧