前几天我看到了关于c语言中i+++i+++i++的问题讨论。有认为值是肯定的,也有认为是不肯定的。我原本倾向于肯定的,即well-defined。原本想NB一把,我们翻标准准确说明它就是well-defined,结果却发现它是undefined。这不,一想那不是更厉害了,直接把前面认为肯定的人都否认了。立即组织材料,本身也写个回复。写的出来后那是至关的有成就感啊,就等着别人来讨论讨论。可是我更渴望别人也以为我观点是对,知足一下本身这颗虚荣心,^_^。不过好伤心啊,没人回复。 html
不过话说回来啊,这个过程挺有趣的。先是本身带着观点去找证据,结果发现观点错了,又找证据证实另外一个观点,最后把一点一点碎片组织起来,就成一篇小文章了。我想啊,那些发表论文的,当写完审查完那一刻确定是至关知足了。开始先是一个一个的lemma, 而后是corollary, 最后就是本身的theorem了。忽然感受写程序的过程也很像。先是小函数,小函数组成大一点的函数,慢慢的本身的程序也就浮现出来。其实,还有不少过程都很像,不是吗?
express
好了,在这就再贴下本身的回答,保存下,也再成就感一下。若是有错误,麻烦你们给指出啦。
数组
标准中提到tranlation有7个阶段,下面是第3阶段的描述(c99 5.1.1.2) 函数
The source file is decomposed into preprocessing tokens and sequences of white-space characters(including comments).这个阶段先于第4阶段的预处理发生。在preprocessing tokens的定义里面包括punctuator。而punctuator里面包括operator。因此根据下面的这两段话(c99 6.4):
If the input stream has been parsed into preprocessing tokens up to a given character, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token.
EXAMPLE 2 The program fragment x+++++y is parsed as x ++ ++ + y我颇有理由认为i+++j 这个表达式确定是分析成i ++ + j。而这些只是preprocessing tokens,在translation的第7阶段才把这些转换成标准中定义的tokens,而后再进行语法的分析。tokens已经被分红那样了,根据优先级,应该是(i++) + y。因此,我认为 i+++i+++i++ 在语法上是被分析为(i++)+(i++)+(i++)。
下面是说明这个式子是undefined的。其实标准里面让它undefined的说明关键就一个了(c99 6.5): post
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.这里的第一句话就让式子undefined的了。对于sequence point,标准里的定义是informative(不懂啥含义)的,其中包括the end of a full expression,而full expression定义以下(c99 6.8)
A full expression is an expression that is not part of another expression or of a declarator.
因此,上诉式子是“Between the previous and next sequence point“无误了。并且标准中还给了两个因为6.5那段而undefined的例子: lua
i = ++i + 1; a[i++] = i;
因此,个人结论是式子i+++i+++i++只能被分析成(i++)+(i++)+(i++),但结果是undefined。 spa
ps:对于6.5那段的第二句我不是太理解,参考了一下别人的说法暂时理解为:若是两个sequence points之间要改变一个object所存的值,那么以前若是有读取此object的值,那么这个以前读的旧值一定是用来肯定新值的。 orm
不知道理解正与否。 htm
参考: token
ISO标准
http://stackoverflow.com/questions/3978625/using-postfix-increment-in-an-l-value
http://c-faq.com/expr/seqpoints.html