C++中多类型整数访问int64_t动态数组的行为问询
C++混合整数类型的数组下标运算行为解析
前提代码
int64_t * arr; arr = new int64_t[M];
其中M为int64_t类型,值足够大,可容纳所有下标访问,不会触发越界。
变量定义与下标场景
int16_t A = 12; int B = INT_MAX; int64_t N = int64_t(B)*int64_t(B); // 无溢出,存储正确计算值 int64_t my_value = arr[N + B + A]; int64_t my_value_2 = arr[A + B + N]; int64_t my_value_3 = arr[B]; int64_t my_value_4 = arr[12L*(Nx+Nx*Ny+1)];
各下标表达式的行为分析
1. arr[N + B + A]
- 运算按左到右顺序执行:首先计算
N + B,N是int64_t,B是int,根据C++整数提升规则,B会被自动转换为int64_t,这一步是64位整数加法,无溢出风险。 - 接着加上
A(int16_t),A同样会被提升为int64_t,最终整个下标表达式结果为int64_t类型。 - 数组下标
arr[X]等价于*(arr + X),这里X会被转换为指针偏移量的标准类型ptrdiff_t(通常为64位,与int64_t兼容),运算合法,结果符合预期。
2. arr[A + B + N]
- 运算从左到右:先计算
A + B,A是int16_t,会被提升为int类型(int范围覆盖int16_t)。但B是INT_MAX,INT_MAX + 12会触发int类型溢出,这属于C++中的未定义行为(UB),溢出后的数值是不可预测的。 - 后续即使将溢出值与
N(int64_t)相加,也无法消除前面的未定义行为,因此整个表达式的结果不可靠。
3. arr[B]
B是int类型,下标运算时会被转换为ptrdiff_t类型:- 64位系统中
ptrdiff_t为64位,完全能容纳INT_MAX; - 32位系统中
ptrdiff_t为32位,INT_MAX刚好是其最大值,也可安全转换。
- 64位系统中
- 只要
M足够大,该下标访问合法,行为正常。
4. arr[12L*(Nx+Nx*Ny+1)]
- 先看内部运算:
Nx*Ny如果是32位整数(比如int),可能触发溢出(未定义行为);若Nx、Ny是int64_t则无问题。 12L是long类型(通常64位系统中long与int64_t兼容),运算时所有参与变量都会被提升为long,最终乘法结果也是long类型。- 最终下标值会被转换为
ptrdiff_t,只要结果在M范围内,访问合法。
内容的提问来源于stack exchange,提问作者Grenix
相关产品推荐
相关产品推荐

