C中的指针比较是签名还是未签名?

tes*_*est 15 c comparison pointers

嗨,我确信这一定是一个常见的问题,但是当我搜索它时,我找不到答案.我的问题主要涉及两个方面.我想比较他们的地址,并确定一个是否比另一个大.我希望在比较期间所有地址都是无符号的.这是真的,它在C89,C99和C++之间有所不同吗?当我用gcc编译时,比较是无符号的.

如果我有两个指针,我正在比较这样:

char *a = (char *) 0x80000000; //-2147483648 or 2147483648 ?  
char *b = (char *) 0x1; 
Run Code Online (Sandbox Code Playgroud)

然后a更大.这是由标准保证的吗?


编辑以更新我想要做的事情.我有一种情况,我想确定如果有算术错误,它不会导致指针超出界限.现在我有数组的起始地址和结束地址.如果出现错误并且指针计算错误,并且在数组内存的有效地址之外,我想确保没有发生访问冲突.我相信我可以通过比较另一个函数返回的可疑指针,并确定它是否在数组的可接受范围内来防止这种情况.负面和正面地址的问题与我是否可以进行比较有关,正如我在原始问题中所讨论的那样.

到目前为止,我很欣赏答案.基于我的编辑,你会说我正在做的是gcc和msvc中未定义的行为吗?这是一个仅在Microsoft Windows上运行的程序.

这是一个简单的例子:

char letters[26];  
char *do_not_read = &letters[26];  
char *suspect = somefunction_i_dont_control(letters,26);  
if( (suspect >= letters) && (suspect < do_not_read) )  
    printf("%c", suspect);  
Run Code Online (Sandbox Code Playgroud)



另一个编辑,在阅读AndreyT的答案后,似乎是正确的.因此我会做这样的事情:

char letters[26];  
uintptr_t begin = letters;  
uintptr_t toofar = begin + sizeof(letters);  
char *suspect = somefunction_i_dont_control(letters,26);  
if( ((uintptr_t)suspect >= begin) && ((uintptr_t)suspect < toofar ) )
    printf("%c", suspect);  
Run Code Online (Sandbox Code Playgroud)


感谢大家!

AnT*_*AnT 25

指针比较无法签名或未签名.指针不是整数.

C语言(以及C++)仅为指向同一聚合(结构或数组)的指针定义相对指针比较.排序很自然:指向数组中索引较小的元素的指针较小.指向先前声明的结构成员的指针较小.而已.

您不能合法地比较C/C++中的任意指针.这种比较的结果没有定义.如果您有兴趣比较存储在指针中的地址的数值,则您有责任首先手动将指针转换为整数值.在这种情况下,您必须决定是使用有符号还是无符号整数类型(intptr_tuintptr_t).根据您选择的类型,比较将是"签名"或"未签名".

  • @R.:void指针上的加法和减法无效的原因是因为这些运算符中的指针必须指向对象类型.该约束*不*适用于关系运算符; 给定`type x [2];`,表达式`(void*)x <(void*)(x + 1)`为真. (2认同)

Jam*_*lis 8

整数到指针的转换是完全实现定义的,因此它取决于您使用的实现.

也就是说,您只能通过关系比较指向同一对象部分的指针(基本上,指向相同结构的子对象或同一数组的元素).您不能比较两个指向任意,完全不相关的对象的指针.

  • @Matt:C99 6.3.2.3/5声明整数到指针的转换是实现定义的.C99 6.5.8/5规定了可以对指针进行关系比较的限制. (2认同)