use*_*248 18 c arrays multidimensional-array undefined-behavior order-of-execution
采取以下措施:
int a(void) {
puts("a");
return 0;
}
int b(void) {
puts("b");
return 1;
}
int c(void) {
puts("c");
return 2;
}
int d(void) {
puts("d");
return 3;
}
Run Code Online (Sandbox Code Playgroud)
以下行为会有可预测的行为吗?
int arr[4][4][4][4];
arr[a()][b()][c()][d()] = 1;
Run Code Online (Sandbox Code Playgroud)
是否保证按这个顺序打印:
int a(void) {
puts("a");
return 0;
}
int b(void) {
puts("b");
return 1;
}
int c(void) {
puts("c");
return 2;
}
int d(void) {
puts("d");
return 3;
}
Run Code Online (Sandbox Code Playgroud)
我知道以下结构是无效的:
int i;
i = i++;
Run Code Online (Sandbox Code Playgroud)
这是因为=是一个无序运算符,因此是否首先计算i或i++是未定义的。在另一个序列点之前访问和修改单个对象是未定义的行为。
换句话说,以下内容是否有效:
int i = 0, arr[4][4][4][4];
arr[i++][i++][i++][i++] = 1;
Run Code Online (Sandbox Code Playgroud)
或者它是否会由于无序的修改和访问而调用未定义的行为i?
根据C标准,[]在索引多维数组时,每个连续的序列点之间是否存在定义的序列点?
需要明确的是,这些示例都与优先级、隐式括号的放置以及运算符对其操作数进行操作的顺序无关。问题在于排序,即操作数本身的求值顺序。
dbu*_*ush 26
以下行为会有可预测的行为吗?
Run Code Online (Sandbox Code Playgroud)int arr[4][4][4][4]; arr[a()][b()][c()][d()] = 1;
不。
虽然数组元素的计算将从左到右进行计算,但由于一个是下一个的操作数,所以不能保证数组索引本身将从左到右进行计算。
更具体地说,arr[a()]是在之前评估的arr[a()][b()],在之前评估的arr[a()][b()][c()],在之前评估的arr[a()][b()][c()][d()]。然而,a()、b()、c()、 和d()可以按任何顺序求值。
C 标准第 6.5p3 节有关表达式的规定:
运算符和操作数的分组由语法指示。除非稍后指定,否则子表达式的副作用和值计算是无序的
关于数组下标的第 6.5.2.1 节没有提及操作数的排序E1[E2],尽管它确实声明了先前的表达式与 完全相同(*((E1)+(E2)))。然后,查看有关间接运算符的第 6.5.3.2 节*和有关加法运算符的第 6.5.6 节+,两者都没有提及以任何方式排序的操作数的评估。因此 6.5p3 适用,并且函数a、b、c和d可以按任何顺序调用。
出于同样的原因,这:
arr[i++][i++][i++][i++] = 1;
Run Code Online (Sandbox Code Playgroud)
触发未定义的行为,因为数组索引的评估彼此之间没有顺序,并且在没有序列点的情况下对同一对象有多个副作用。
use*_*248 14
不保证多维数组访问的索引按任何特定顺序进行计算。演示显示了从左到右调用的函数,但在 Godbolt 中选择不同的编译器会从右到左评估它们。
经过进一步调查,第二个代码示例导致 Clang 发出警告:
warning: multiple unsequenced modifications
to 'i' [-Wunsequenced]
arr[i++][i++][i++][i++] = 1;
^ ~~
Run Code Online (Sandbox Code Playgroud)
多维数组的访问可以分解为一系列,(array)[index]其中array是多维数组的较高维度(arr本身就是最高维度),index是索引表达式,例如函数调用或i++表达式。
标准认为lhs[rhs]等于*((lhs)+(rhs)),因此不确定是否首先评估任何给定的index或array它的索引,因为该+运算符是无序的。array在所有不是自身的情况下arr,评估都涉及在更高的维度上array评估它。 index
因此,评估多维数组访问的索引的顺序是不确定的。
| 归档时间: |
|
| 查看次数: |
2432 次 |
| 最近记录: |