考虑以下C程序:
int i = 0;
int post_increment_i() { return i++; }
int main() {
i = post_increment_i();
return i;
}
访问易失性对象、修改对象、修改文件,或者调用执行那些操作中的任何操作的函数都是副作用,它们是执行环境状态的改变。表达式的计算通常包括值计算和副作用的启动。用于lvalue表达式的值计算包括确定指定对象的标识。
Sequenced before是单线程执行的计算之间的非对称、传递、成对关系,它导致这些计算之间的部分顺序。给定任意两个评价A和B,如果A排序在B之前,那么A的执行应先于B的执行(相反,如果A排序在B之前,那么B排序在A之后)如果A没有排序在B之前或之后,那么A和B没有排序。当A在B之前或之后测序时,评估A和B的测序是不确定的,但未指明哪一个。13表达式A和B的评估之间存在一个测序点意味着与A相关的每一个值计算和副作用都在与B相关的每一个值计算和副作用之前测序(附录C中给出了该测序点的摘要)
13)未排序的评估可以交错执行,不确定排序的评估不能交错执行,但可以按任何顺序执行。
如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值进行的值计算没有排序,则行为是未定义的。如果一个表达式的子表达式有多个允许的顺序,那么如果这种未排序的副作用发生在任何一个顺序中,则该行为是未定义的。
6.5.2.2函数调用
在函数指定符和实际参数的求值之后但在实际调用之前有一个序列点。调用函数(包括其他函数调用)中的每一个在被调用函数主体执行之前或之后未进行特定排序的计算,都相对于被调用函数的执行进行不确定的排序。94
赋值运算符在左操作数指定的对象中存储值。[...]更新左操作数的存储值的副作用在左操作数和右操作数的值计算之后排序。操作数的计算是不排序的。
6.8语句和块
完整表达式是不是另一个表达式或声明符的一部分的表达式。以下每一项都是完整的表达式:[...]表达式语句中的表达式;[...]返回语句中的(可选)表达式。在一个完整表达式的求值和下一个要求值的完整表达式的求值之间有一个序列点。
第一种选择似乎是成立的,理由如下:
>
考虑以下规则:调用函数(包括其他函数调用)中的每个计算,如果在被调用函数主体执行之前或之后没有进行特定的排序,则相对于被调用函数的执行进行不确定的排序。6.5.2.2.假设A:main中赋值运算符的副作用就是这样一个“评估”。假设B:短语“被调用函数的执行”既包括后缀增量运算符的值计算,也包括后缀增量运算符的副作用。根据这些假设和上述规则,可以得出以下结论:I)后缀增量运算符的值计算和副作用都在main中赋值运算符的副作用之前排序,或者II)后缀增量运算符的值计算和副作用都在main中赋值运算符的副作用之后排序。
[我的答案是基于更简单的C99标准,而且C11极不可能引入突破性的变化:]
此代码的这种行为定义良好:main
返回0
。在return
语句的完整表达式之后有一个序列点(参见C99,附件C),因此i++
的副作用在赋值给main
中的i
之前生效。
我一直在温习我未定义的行为规则,并阅读了以下内容: 未定义的行为和序列点 为什么f(i=-1,i=-1)行为未定义 为什么`x-- 在C 11中,“i = i 1”是否表现出未定义的行为? 最后有三个问题: < li >形式为< code>i=i 的术语的未定义行为规则是否适用于非整型?(表达式应翻译为< code > I . operator(I . operator(I)),由于每个函数调用都
尽管标题出现了,但这并不是一个哲学问题。 从未初始化的数组读取 使用错误数据 使用不可移植构造。(即内存分配的细节1) 导致具有的行为 标准没有要求产生可预测的效果 我会称之为“未定义的行为”。但也许我错过了什么(?) null null
好吧,所以那里没有UB。现在我的问题是,如果将赋值运算符从更改为(或类似运算符),会发生什么。 表达式的求值是否导致未定义的行为? 在我看来,这个标准在这里似乎自相矛盾。由于的LHS仍然是一个L值(其RHS仍然是一个prvalue),就(1)和(2)而言,同样的推理也适用;在上的操作数的计算中没有未定义的行为。对于(3),复合赋值的操作(更准确地说是该操作的副作用;如果需要,它的值计算在任何情况下
根据 cpp 偏好(强调我的): 核心常量表达式是指在任何子表达式中不包含以下任何一项的任何表达式...) 另一方面,指针上有几个表达式的结果不是未定义的,而是未指定的(参见[expr.rel]/3),例如: 代码编译时没有 gcc 的问题,但不是 clang 的编译,它陈述了毫无疑问是正确的: 不同基类的子对象的地址比较有未指定的 但是(据我理解)根据cppreference,它不应该阻止编译器
此代码为-O1和-O2提供不同的结果: 那么这是一个错误吗?或者其中是否存在某种未定义的行为,编译器有权为其提供不同的结果? 据我从C99标准中可以看出,遍历所有值的循环是有效的,因为最大无符号整数值的增量被很好地定义为导致零。 涉及无符号操作数的计算永远不会溢出,因为不能由结果无符号整数类型表示的结果将被减少为比结果类型可以表示的最大值大一的数的模。
问题内容: React 在promise中没有定义。这是我的代码: 这是错误代码: 问题答案: 可能没有约束力。 如果您可以使用ES6语法,请尝试用箭头函数替换。它会自动绑定: 或手动绑定: