C标准是否保证多维数组下标表达式的求值顺序?
C标准中多维数组下标表达式的求值顺序与序列点问题
核心结论
C标准没有对多维数组下标中各表达式的求值顺序做出任何保证,连续的[]运算符之间也不存在定义的序列点。各下标表达式的求值顺序属于「未指定行为(unspecified behavior)」——编译器可以选择任意顺序求值,只要符合语法规则即可,标准不强制统一。
示例一:带副作用的函数调用下标
先看给出的函数定义:
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; }
对于代码:
int arr[4][4][4][4]; arr[a()][b()][c()][d()] = 1;
这段代码的行为不可预测。虽然GCC等部分编译器会选择从左到右的顺序调用函数,但这只是编译器的实现细节,并非C标准的要求。换用其他编译器(或同一编译器的不同优化选项),函数调用顺序完全可能变成右到左或其他任意顺序,输出结果也会随之变化。
示例二:含自增操作的下标
对于代码:
int i = 0, arr[4][4][4][4]; arr[i++][i++][i++][i++] = 1;
这段代码属于未定义行为(undefined behavior),而非等价于arr[0][1][2][3] = 1;。原因是:在没有序列点的上下文里,对同一个对象i既进行了多次修改(i++),又进行了多次值访问,C标准完全不规定这些操作的执行顺序。编译器可以自由选择任意顺序来计算各个i++,最终得到的数组下标组合可能千差万别,甚至可能触发其他异常行为。
内容的提问来源于stack exchange,提问作者CPlus
相关产品推荐
相关产品推荐

