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

问题描述 投票:0回答:1

定义

int a = 0, b = a++, c = a++;
在 C 中是否有定义的行为?

或者几乎等价地,对象定义中的

,
是否像表达式中的逗号运算符一样引入序列点?

对于 C++ 也提出了类似的问题:

C++ 广泛接受的答案是 是的,它已完全定义 根据 C++11 标准第 8/3 段:

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

虽然本段仅涉及语法分析阶段,对于运行时的操作顺序还不够精确。

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

编辑:之前曾问过类似的问题:

多个对象声明中的逗号是否会像逗号运算符一样引入序列点?

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

c language-lawyer undefined-behavior definition sequence-points
1个回答
2
投票

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

从下面的文本部分总结,声明语句中的初始值设定项是排序的,保证发布的声明中的初始值设定项表达式不会调用未定义的行为,甚至不确定的结果。它们已完全定义。

来自§5.1.2.3

之前排序的是不对称、传递、成对关系 在单个线程执行的评估之间,这会导致 这些评价之间的偏序。给定任意两个评估 A 和 B,如果A排序在B之前,则A的执行应先于 B 的执行。(相反,如果 A 排在 B 之前,则 B 是 排序在 A 之后。)如果 A 没有排序在 B 之前或之后,则 A 和 B 是未排序的。评估 A 和 B 是不确定的 当 A 在 B 之前或之后排序时,则已排序,但它是 未指定哪一个。13) 之间存在序列点 表达式 A 和 B 的求值意味着每个值计算 与 A 相关的副作用在每个值之前排序 与 B 相关的计算和副作用。(总结 序列点在附录 C 中给出。)

附件C中提供的相关段落:

以下是5.1.2.3中描述的顺序点: (3) ...

在完整表达式的求值和下一个完整表达式的求值之间 要评估的表达式。以下为完整表达:完整 可变修改类型的声明符;一个初始化器不是 复合文字的一部分 (6.7.9);表达式中的表达式 声明(6.8.3);选择语句的控制表达式 (如果或开关)(6.8.4); a while 或 do 的控制表达式 声明(6.8.5); for 的每个(可选)表达式 声明(6.8.5.3); return 语句中的(可选)表达式 (6.8.6.4).
(强调我的)

© www.soinside.com 2019 - 2024. All rights reserved.