定义int a = 0, b = a++, c = a++;是否用C定义了行为?

或者几乎等同地,对象定义中的,是否为表达式中的逗号操作符引入了序列点?

类似的问题也被问到了C++:

根据C++11标准的第8/3段,C++被广泛接受的答案是Yes, it is fully defined:

声明中的每个init-declarator都被单独分析,就像它自己在声明中一样

尽管这一段只提到了语法分析阶段,对于运行时操作的顺序并不是很精确.

C语言的情况如何?C标准是否定义了行为?

EDIT:以前也有人问过类似的问题:

Does the comma in a declaration for multiple objects introduce a sequence point like the comma operator?

然而,答案似乎专门针对C11草案,可能不适用于C标准的较新版本,因为信息丰富的附件C的措辞发生了变化,似乎也与标准文本不完全一致.

推荐答案

"Does the definition int a = 0, b = a++, c = a++; have defined behavior in C?"...

在当前的C标准ISO/IEC9899:2017中,程序执行包含在第5.1.2.3(3)节中,其中包括对排序和副作用的讨论.原文转载如下,以供参考.

从下面的文本部分总结,声明语句中的初始值设定项是按顺序排列的,以保证声明中的初始值设定项表达式已发布...

 int a = 0, b = a++, c = a++;

which describes an "...init-declarator-list [which] is a comma-separated sequence of declarators," (section 6.7 Declarations)
...will not invoke undefined behavior, or even indeterminate results. Each comma separated expression is guaranteed to be sequenced starting from left, and not moving to the right until all evaluations and side-effects for the current expression are resolved and complete. In this way the results of each expression is fully defined.

摘自§5.1.2.3

"Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread, which induces a partial order among those evaluations. Given any two evaluations A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. (Conversely, if A is sequenced before B, then B is sequenced after A.) If A is not sequenced before or after B, then A and B are unsequenced. Evaluations A and B are indeterminately sequenced when A is sequenced either before or after B, but it is unspecified which.13) The presence of a sequence point between the evaluation of expressions A and B implies that every value computation and side effect associated with A is sequenced before every value computation and side effect associated with B. (A summary of the sequence points is given in annex C.)"

附件C规定的有关段落:

"The following are the sequence points described in 5.1.2.3:"+(3) ......

"Between the evaluation of a full expression and the next full expression to be evaluated. The following are full expressions: a full declarator for a variably modified type; an initializer that is not part of a compound literal (6.7.9); the expression in an expression statement (6.8.3); the controlling expression of a selection statement (if or switch) (6.8.4); the controlling expression of a while or do statement (6.8.5); each of the (optional) expressions of a for statement (6.8.5.3); the (optional) expression in a return statement (6.8.6.4)".
(emphasis mine)

C++相关问答推荐

理解C中的指针定义

CC crate 示例不会与C函数链接

在32位处理器上优化53—32位模计算>

DPDK-DumpCap不捕获端口上的传入数据包

堆栈在作用域阻塞后会被释放吗?

核心转储文件中出现奇怪的大小变化

Can函数指针指向C++中具有不同参数连续性的函数

如何编写一个for循环来计算C中各项的总和?

For循环中的变量行为不符合预期.[C17]

从C文件中删除注释

指向不同类型的指针是否与公共初始序列规则匹配?

在运行时判断C/C++指针是否指向只读内存(在Linux操作系统中)

在C中使用无符号整数模拟有符号整数

C中的char**v*char[]

在printf()中用%.*S格式填充长度为0的字符串是否会调用任何UB?如果是,是哪一个?

解密Chrome加密密钥

WSASocket在哪里定义?

中位数和众数不正确

是什么阻止编译器优化手写的 memcmp()?

为什么创建局部变量的指针需要过程在堆栈上分配空间?