是赋值x=1;根据C17,是否始终存在未定义的行为?

是赋值x=1;根据C17,是否始终存在未定义的行为?,c,language-lawyer,c17,C,Language Lawyer,C17,我正在看C17,N2176的最终草稿。在这里,我关心的是哪种带有副作用的表达方式会使它的行为不明确 在本标准第6.5节的表述中,第2段以以下内容开头: 如果标量对象上的副作用相对于 对同一标量对象或值的不同副作用 使用相同标量对象的值进行计算时,行为为 未定义 据我所知,表达式x=1的计算既会产生一个值,也会引起一个副作用,即改变x指定的对象的值。决定因素将是副作用是否以任何方式排序,与使用x指定的对象值的值计算有关 第6.5.16节“赋值运算符”中的描述包含以下内容: 更新左操作数的存储值的副

我正在看C17,N2176的最终草稿。在这里,我关心的是哪种带有副作用的表达方式会使它的行为不明确

在本标准第6.5节的表述中,第2段以以下内容开头:

如果标量对象上的副作用相对于 对同一标量对象或值的不同副作用 使用相同标量对象的值进行计算时,行为为 未定义

据我所知,表达式x=1的计算既会产生一个值,也会引起一个副作用,即改变x指定的对象的值。决定因素将是副作用是否以任何方式排序,与使用x指定的对象值的值计算有关

第6.5.16节“赋值运算符”中的描述包含以下内容:

更新左操作数的存储值的副作用是 在左操作数和右操作数的值计算之后排序

这并不能解决整个赋值的值计算顺序和赋值的副作用

还有一句话:

赋值表达式的左操作数的值位于 赋值,但不是左值

指定最终值应该是什么,但不要求进行任何排序。我没有看到任何其他文字提到排序的副作用和价值

我知道,当作为完整语句编写时,x=1;未使用赋值的值。然而,标准规定该值被丢弃。这意味着,它就像是先对值求值,然后丢弃,因此仍应触发未定义的行为


标准中是否有任何其他部分使该语句行为未定义?

赋值表达式的值不是对赋值对象的使用。这是因为x=1,in,比如y=x=1的值不是通过x的左值转换获得的,而是根据C 2018 6.5.16 3计算赋值表达式的值:

…赋值表达式在赋值后具有左操作数的值

它还说:

…赋值表达式的类型是左值转换后左操作数的类型

这是关于类型,而不是值,但它使用虚拟语气“would have”表明“左值转换”是虚构的;它实际上并没有发生。因此赋值表达式不是通过读取左操作数获得其值;它的价值仅仅是操作的结果

那里有一个脚注说:

允许实现读取对象以确定值,但不需要读取,即使对象具有volatile限定类型


这告诉我们,左操作数实际上可以用来计算赋值表达式的值。但是,这是一条可以通过这样做来实现的语句,而不是一条在C计算模型中这是赋值表达式语义的一部分的语句。

赋值表达式的值不是对赋值对象的使用。这是因为x=1,in,比如y=x=1的值不是通过x的左值转换获得的,而是根据C 2018 6.5.16 3计算赋值表达式的值:

…赋值表达式在赋值后具有左操作数的值

它还说:

…赋值表达式的类型是左值转换后左操作数的类型

这是关于类型,而不是值,但它使用虚拟语气“would have”表明“左值转换”是虚构的;它实际上并没有发生。因此赋值表达式不是通过读取左操作数获得其值;它的价值仅仅是操作的结果

那里有一个脚注说:

允许实现读取对象以确定值,但不需要读取,即使对象具有volatile限定类型


这告诉我们,左操作数实际上可以用来计算赋值表达式的值。但是,这是一种可以通过这样做来实现的声明,不是说这是C计算模型中赋值表达式语义的一部分。

您在部分引用的段落中的最后一句话是更新左操作数存储值的副作用,它是在左操作数和右操作数的值计算之后排序的。操作数的求值是未排序的。-修改的顺序是最后一个。@StoryTeller UnslanderMonica:问题并不是问与操作数的值计算相关的副作用的顺序。它询问副作用相对于计算值的顺序
赋值表达式的重新定义。例如,考虑y=x=1,它由于副作用而修改x,并且“使用”x赋值给y.@ EricPostpischil,但它不使用x赋值给y。它使用表达式x=1。@StoryTeller UnslanderMonica:因此我的意思不是引号和我的答案。尽管标准中有一个脚注说,实现实际上可以读取x来获得值!您在部分引用的段落中的最后一句话是更新左操作数存储值的副作用,它是在左操作数和右操作数的值计算之后排序的。操作数的求值是未排序的。-修改的顺序是最后一个。@StoryTeller UnslanderMonica:问题并不是问与操作数的值计算相关的副作用的顺序。它询问与赋值表达式的值计算相关的副作用的顺序。例如,考虑y=x=1,它由于副作用而修改x,并且“使用”x赋值给y.@ EricPostpischil,但它不使用x赋值给y。它使用表达式x=1。@StoryTeller UnslanderMonica:因此我的意思不是引号和我的答案。尽管标准中有一个脚注说,实现实际上可以读取x来获得值!