sch*_*ine 5 c sequence-points language-lawyer order-of-execution
我对CPPReference说 postincrement\xe2\x80\x99s 值评估在其副作用之前排序这一事实感到困惑,但 preincrement 没有这样的保证。
\n我现在想出了一个例子,这很重要,但我不确定我的分析是否正确。
\n据我了解,这两个程序的不同之处在于第一个包含 UB,而第二个则不包含:
\n#include <stddef.h>\n#include <stdio.h>\n\nint main(void) {\n int arr[] = {0, 1, 2};\n int i = 1;\n int x = ++arr[arr[i]];\n}\nRun Code Online (Sandbox Code Playgroud)\n#include <stddef.h>\n#include <stdio.h>\n\nint main(void) {\n int arr[] = {0, 1, 2};\n int i = 1;\n int x = arr[arr[i]]++;\n}\nRun Code Online (Sandbox Code Playgroud)\n我对这个表达式的分析++arr[arr[i]]如下:
i值计算之前排序arr[i]arr[i]值计算之前排序arr[arr[i]]arr[arr[i]]值计算之前排序++arr[arr[i]]++arr[arr[i]]与这些相关的副作用是无序的。arr[arr[i]]因为它没有被使用。arr[arr[i]]引用与 相同的标量对象arr[i]。++arr[arr[i]]修改标量对象arr[arr[i]],但它的访问顺序与 by 的顺序无关arr[i]。然而,如果我们使用后增量,我们会引入一个新的序前关系: 的值计算arr[arr[i]]++在其副作用之前排序。因此,通过传递性,副作用不再是无序的arr[i]。
但是,我不确定这是否准确。特别是,我不确定增量/增量前的评估是如何准确定义的。它是否对其操作数执行值计算?如果是的话,这是否意味着++*ptrUB 是 UB 而(*ptr)++不是?如果不是,那么如何执行完整表达式的值计算\xe2\x80\x94任何运算符都可以访问左值表达式的值而不对该表达式执行值计算吗?