gpt4 book ai didi

c++ - 使用无符号 "negative"数字递减指针

转载 作者:行者123 更新时间:2023-11-30 21:41:48 25 4
gpt4 key购买 nike

下面的示例在调用look_back_1()或look_back_2()时应该崩溃。原因:当对无符号变量求反时,结果应保持无符号。

#include <stdio.h>


int look_back_1(int *arr, unsigned int nmElems, unsigned long dist)
{
int *elem = arr + nmElems;
elem += -dist;
return (*elem);
}


int look_back_2(int *arr, unsigned int nmElems, unsigned int dist)
{
int *elem = arr + nmElems;
elem += -dist;
return (*elem);
}


int main(int argc, char **argv)
{
int arr[100] = { 0, };
printf("1. %d\n", look_back_1(arr, 100, 1)); // <NEEDS TO CRASH, BUT WORKS????>>
printf("2. %d\n", look_back_2(arr, 100, 1)); // <<CRASH!!!!!>>
}

当进行数组越界访问时,GCC 4.5 在每个函数调用中都会崩溃。编译器针​​对这两种情况发出 NEG 操作码。

GCC 6.1 或 Clang 仅在调用 int 版本时才会崩溃。但当它们为无符号长版本发出 SUB 操作码时,它们都避免了崩溃。

他们可以这样做吗?

最佳答案

[编辑]这是问题先前版本的答案,它显示了使用参数 dist==1 调用这些函数时出现的问题

-(unsigned long)1 定义明确且环绕。只是ULONG_MAX。出于同样的原因,-(unsigned int)UINT_MAX

数组边界之外的指针运算会导致未定义的行为,因此 GCC 忽略这种可能性是完全合理的。例如,他们可以将 x64 上的指针视为带有环绕的 64 位整数。将 64 位 ULONG_MAX 添加到具有环绕功能的 64 位指针只会将指针减少 -1,这就是环绕的工作原理。添加 32 位 UINT_MAX 点与您的 int[100] 相差甚远。

因此,您看到的行为是未定义行为的一个完全有效的结果。然而它是完全不可靠的。优化器可能知道您添加的元素数量不能超过数组中允许的最大数量(64 位平台上的 4 字节整数为 2^62),并据此进行假设。

关于c++ - 使用无符号 "negative"数字递减指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45191362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com