以下语句在ANSI C中是否有效?它有效吗?

Ana*_*oly 6 c c89 sequence-points language-lawyer

在准备考试时,ANSI CI遇到了以下问题 -

以下声明是否有效?
如果没有,请进行必要的更改以使其有效.

原始陈述是:test(i++,i++);它无效,因为根据K&R p202,行为未定义

参数的评估顺序未指定

但我可以将其更改为以下声明吗?test(i+=2, i+=3)

我在K&R或任何其他来源中没有看到这样的记录的问题.但XCode编译它并在没有任何警告的情况下运行.

小智 12

两者都是有效的陈述,即合法的C,在这两种情况下,行为都是未定义的.

  • 这取决于你的意思是"有效".很多人会声称具有未定义行为的程序不是"有效",并且这些声明至少与您的合法一样合法. (6认同)
  • 不要混淆_valid_(在语法上)和_correct_(或根据标准"严格遵守")程序. (3认同)

Sou*_*osh 12

要添加到现有答案,关键点是声明

test(i+=2, i+=3)
Run Code Online (Sandbox Code Playgroud)

尽可能多地调用未定义的行为

test(i++,i++);
Run Code Online (Sandbox Code Playgroud)

因为,在这两种情况下,在函数参数列表中没有为逗号分隔符安排序列点,因此,您最终会单个序列点的范围内两次修改同一变量的值.这会调用未定义的行为.


pho*_*xis 7

在变更之前和之后,语句在语法上都是有效的.但问题仍然存在.如果要修改参数中的对象,则未指定评估顺序.

C99第6.5.2.2节第10段

函数指示符的评估顺序,实际参数和实际参数中的子表达式是未指定的,但在实际调用之前有一个序列点.

根据第3.4.4节第1段

未指明的行为

使用未指明的值,或本国际标准提供两种或更多种可能性的其他行为,并且在任何情况下都不会对其进行任何进一步的要求.

另一方面,第3.4.3节第1段说明

未定义的行为

使用不可移植或错误的程序结构或错误数据时的行为,本国际标准不要求

在订单或评估的情况下,它可以按任何顺序完成,具体取决于编译器如何生成代码,它可以按任何顺序存储在内存中,也可以通过寄存器传递参数.生成代码后,二进制文件在任何地方都会表现相同.因此,对于一个单独的二进制文件,结果每次都是相同的,但是根据编译器的决定,事情可能会发生变化.

最好的想法是避免任何看似不正确或花哨的东西.如果有疑问,可能是未定义的,未指定的,实现定义的行为.因此,你可以使同样的事情明确无误,确定如下.

test (i, i+1);
i += 2;
Run Code Online (Sandbox Code Playgroud)

要么

test (i+1, i);
i+= 2;
Run Code Online (Sandbox Code Playgroud)

取决于您想要的顺序.