此代码片段摘自一本 linux 书籍。 如果不适合在此处发布代码片段,请告诉我。 我会删除它。谢谢。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char buf[30];
char *p;
int i;
unsigned int index = 0;
//unsigned long index = 0;
printf("index-1 = %lx (sizeof %d)\n", index-1, sizeof(index-1));
for(i = 'A'; i <= 'Z'; i++)
buf[i - 'A'] = i;
p = &buf[1];
printf("%c: buf=%p p=%p p[-1]=%p\n", p[index-1], buf, p, &p[index-1]);
return 0;
}
在 32 位操作系统环境中: 无论索引的数据类型是 unsigned int 还是 unsigned long,这个程序都可以正常工作。
在 64 位操作系统环境中: 如果 index 被声明为 unsigned int,则相同的程序将运行到“核心转储”。 但是,如果我只将索引的数据类型从 unsigned int 更改为 a) unsigned long 或 b) unsigned short, 这个程序也很好用。
书上的原因只告诉我64位会因为非负数导致core-dump。但是我不知道为什么 unsigned long 和 unsigned short 工作但 unsigned int。
让我感到困惑的是
p + (0u -1) == p + UINT_MAX
当索引为无符号整数时。
但是,
p + (0ul - 1) == p[-1]
当索引为无符号长整数时。
我卡在这里了。
如果有人能帮忙详细说明一下,不胜感激!
谢谢。
这是我的 32 位(RHEL5.10/gcc 版本 4.1.2 20080704)的一些结果
和64位机器(RHEL6.3/gcc版本4.4.6 20120305)
我不确定 gcc 版本在这里是否有任何区别。 所以,我也粘贴了信息。
在 32 位上:
我尝试了两个改变:
1) 将unsigned int index = 0
修改为unsigned short index = 0
。
2) 将unsigned int index = 0
修改为unsigned char index = 0
。
程序可以正常运行。
index-1 = ffffffff (sizeof 4)
A: buf=0xbfbdd5da p=0xbfbdd5db p[-1]=0xbfbdd5da
看来索引的数据类型会因为-1而提升为4字节。
在 64 位上:
我尝试了三个改变:
1) 将unsigned int index = 0
修改为unsigned char index = 0
。
It works!
index-1 = ffffffff (sizeof 4)
A: buf=0x7ffff304ae0 p=0x7ffff304ae1 p[-1]=0x7ffff304ae0
2) 将unsigned int index = 0
修改为unsigned short index = 0
。
It works!
index-1 = ffffffff (sizeof 4)
A: buf=0x7fff48233170 p=0x7fff48233171 p[-1]=0x7fff48233170
3) 将unsigned int index = 0
修改为unsigned long index = 0
。
It works!
index-1 = ffffffff (sizeof 8)
A: buf=0x7fffb81d6c20 p=0x7fffb81d6c21 p[-1]=0x7fffb81d6c20
但是,只有
unsigned int index = 0
在最后一个 printf 处进入核心转储。
index-1 = ffffffff (sizeof 4)
段错误(核心转储)
最佳答案
不要欺骗编译器!
向 printf
传递一个 int
它需要一个 long
(%ld
) 是未定义的行为。
(创建一个指向任何有效对象外部(而不仅仅是在一个对象后面)的指针也是 UB ......)
更正格式说明符和指针算法(包括作为特殊情况的索引),一切都会正常工作。
UB 包括“它按预期工作”以及“灾难性故障”。
顺便说一句:如果您礼貌地向编译器询问所有警告,它会警告您。使用 -Wall -Wextra -pedantic
或类似的。
关于c - Unsigned int 从 32 位到 64 位操作系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25228791/