jor*_*dan 1 c integer-overflow
我在32位架构上使用C语言.
如果我使用array[-2147483635]为什么C将其转换为array[13]?
-2147483635 在Two的补充是 10000000000000000000000000001101b
是否需要左位并将其转换为0以便它变为
00000000000000000000000000001101b,即13???
我认为它不适合size_t.因为size_t翻译-2147483635成4294967264.
它不会转化为array[13],但适当地转化为array[-2147483635].但是,这可能仍会导致未定义的行为.例如,在32位x86上,程序集为
char f(char * a) { return a[-2147483635]; }
int g(int * a) { return a[-2147483635]; }
Run Code Online (Sandbox Code Playgroud)
可能看起来像:
f:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movzbl -2147483635(%eax), %eax
popl %ebp
ret
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 52(%eax), %eax
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)
在此处查看在线示例.所以对于char数组看起来都很好,但你可以看到整数数组的溢出(movl 52(%eax), %eax其中52是4×13).这是由未定义的行为引起的,因为在32位系统上,任何数组或指针都不可能存在索引为-2147483635的元素.对于数组,它会指向数组的第一个元素之前的某个元素,因此是未定义的行为.对于任何指针,如果你只有一个最大的2个32或4294967296字节的内存,并让说,array点到最后一个字节索引2 32 -1或4294967295,则-2147483635个元素必须驻留在内存地址4294967295 + ((-2147483635)*sizeof(int))是4294967295 - 8589934540哪个-4294967245.这样的内存地址没有意义.
有关详细信息,请参阅§6.5.6(8)中的cppreference或C标准.