这是printf函数的未定义行为吗?

时间:2016-06-06 18:26:06

标签: c

 int c=2; printf("%d %d %d",c,c<<=2,c>>=2);

这是未定义的行为吗?

 int c=2;
 printf ("%d %d %d",c,c<<=2,c>>=2);

1 个答案:

答案 0 :(得分:0)

行为未定义。

  

[C99: 4/2]:如果违反了约束之外出现的''shall''或''shall not''要求,则行为未定义。未定义的行为在本国际标准中以“未定义的行为”或“省略行为的任何明确定义”的方式表示。这三者之间的重点没有区别;他们都描述了“未定义的行为”。

     

[C99: 5.1.2.3/2]:访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用,11)这些是执行环境状态的变化。表达的评估可能产生副作用。在称为序列点的执行序列中的某些特定点处,先前评估的所有副作用应该是完整的,并且不会发生后续评估的副作用。 (序列点的摘要见附件C.)

     

[C99: C/1]:以下是5.1.2.3中描述的序列点:    - 在评估参数后调用函数(6.5.2.2)。    - 以下运算符的第一个操作数的结尾:逻辑AND&amp;&amp; (6.5.13);逻辑OR || (6.5.14);条件? (6.5.15);逗号,(6.5.17)。    - 完整声明者的结尾:声明者(6.7.5);    - 完整表达式的结束:初始化器(6.7.8);表达式中的表达式(6.8.3);选择语句的控制表达式(if或switch)(6.8.4); while或do语句的控制表达式(6.8.5); for语句的每个表达式(6.8.5.3);返回语句中的表达式(6.8.6.4)。    - 在库函数返回之前(7.1.4)。    - 与每个格式化输入/输出函数转换说明符(7.19.6,7.24.2)相关的操作之后。    - 在每次调用比较函数之前和之后,以及对比较函数的任何调用和作为参数传递给对象的任何移动之间(7.20.5)。

     

[C99: 6.2.2.2/10]:未指定函数指示符,实际参数和实际参数中的子表达式的评估顺序,但在实际调用之前有一个序列点。

而且,尽管我不能证明是负面的,但没有措辞可以对varargs案例作出例外处理。