【发布时间】:2016-05-22 19:44:06
【问题描述】:
在探索将指针转换为字符串时,intptr_t 和 uintptr_t 之类的
void *p;
char sp[100];
snprintf(sp, sizeof sp, "%p, p);
intptr_t ip = (intptr_t) p;
我想知道 2 个指针 some_type *a; some_type *b; 和它们的相等性在转换时如何转移。
案例 1:两个指针指向相同位置(对象、对象内的偏移量、1-过去、函数、数组)但具有不同的位模式,或者是 2 个具有不同位模式的空指针位模式。这种情况很难在某些平台上创建,如果有的话。
当然,它们作为指针比较相等(C11 §6.5.9 6)。然而,作为字符串,intptr_t 或 uintptr_t,我期望它们是不同的,但 认为相同是可以的。
Q1 案例 1 指针转换(转换为字符串、
intptr_t、uintptr_t)相同或不同 - 是否都符合结果?
情况 2(常见情况):所有其他指针对混合但不是情况 1:空值、对象、对象内、1-过去对象、函数...中的任何一个
Q2 Case 2 指针
a,b:必须a == b转换为字符串,intptr_t,uintptr_t有相同的结果(使用!strcmp(),==,==)?
使用"%p" 打印指针可能不恰当地称为“转换”,但希望仍能传达这个想法。
测试代码以尝试一些可能性。
void ptr_compare(void *pa, void *pb,
bool *pcmp, bool *mcmp, bool *scmp, bool *icmp, bool *ucmp) {
// pointer compare
*pcmp = pa == pb;
// memory compare
*mcmp = memcmp(&pa, &pb, sizeof pa) == 0;
// string compare
char sa[100];
snprintf(sa, sizeof sa, "%p", pa);
char sb[100];
snprintf(sb, sizeof sb, "%p", pb);
*scmp = !strcmp(sa, sb);
// signed compare
intptr_t ia = (intptr_t) pa;
intptr_t ib = (intptr_t) pb;
*icmp = ia == ib;
// unsigned compare
uintptr_t ua = (uintptr_t) pa;
uintptr_t ub = (uintptr_t) pb;
*ucmp = ua == ub;
}
void ptr_test(void *pa, void *pb) {
bool pcmp, mcmp, scmp, icmp, ucmp;
ptr_compare(pa, pb, &pcmp, &mcmp, &scmp, &icmp, &ucmp);
// If same bit pattern ...
if (mcmp) {
if (pcmp && scmp && icmp && ucmp) return;
// else different bit pattern ...
} else {
if (!pcmp && !scmp && !icmp && !ucmp) return;
}
// Something interesting !
printf("ptra:%p ptrb:%p --> pcmp:%d mcmp:%d scmp:%d icmp:%d ucmp:%d\n", pa,
pb, pcmp, mcmp, scmp, icmp, ucmp);
}
int main(void) {
char p[1];
void *ptrs[] = { 0, NULL, "123", "123", "456", p, p, main };
for (size_t ia = 0; ia < sizeof ptrs / sizeof ptrs[0]; ia++) {
for (size_t ib = 0; ib < sizeof ptrs / sizeof ptrs[0]; ib++) {
ptr_test(ptrs[ia], ptrs[ib]);
}
}
puts("Done");
return 0;
}
结果。在两个经过测试的平台上,我显然无法创建“有趣的东西!”
Done
【问题讨论】:
标签: c pointers language-lawyer