5

我有一个结构

struct detail {
int id;
uintptr_t init;
// blah blah
};
struct detail info;
info.id = 1;
info.init = (uintptr_t)NULL;

我必须使init成员为 NULL。如果我进行类型转换(或不进行类型转换),可能/可能不会发生什么NULL?如果我直接将其分配为 NULL 会怎样?info.init = NULL;它对运行时错误有什么影响吗?它编译得很好。但是代码的执行是我主要关心的。

谢谢

4

3 回答 3

7

标准中不保证 ifptr是空指针,那么(uintptr_t)ptris 0

如果您不关心空指针和零整数不等价的系统,那info.init = 0;很好。

init成员具有整数类型,不能“设为空”。您可以分配0给它,也可以将空指针转换为的结果分配给它uintptr_t。在几乎所有的 C 实现中,这些都是相同的。但这并不能保证,并且在某些系统上它是不一样的。

NULL可能是空指针,也可能是整数常量0。在后一种情况下,标准中有一个保证,(uintptr_t)(NULL)0. 因此,可能存在info.init = NULL; (void*)(info.init);未定义行为的实现。如果 null 的整数等效值不为 0,则不会导致 null 指针,并且计算无效指针值是 UB。

因此,如果您想保证info在转换为指针类型时会产生空指针,那么为了真正的可移植性,您应该这样做info.init = (uintptr_t)(void*)(NULL);uintptr_t您可以选择通过包含将要转换为的指针类型而不是void*. 存储 a 的充分理由很少uintptr_t,因此提示正在发生的事情可能会对读者有所帮助。

请注意,标准中保证转换为指针类型的零值常量表达式是空指针。这并不意味着转换为指针类型的零值非常量表达式是空指针。这也不意味着转换为整数类型的空指针为 0。在大多数实现(包括所有“现代”实现)中,最后两件事恰好是真的。

于 2013-03-15T10:21:13.770 回答
2

NULL 是一个内置常量,其值与系统上的空指针匹配。将常量值分配给与系统上的指针大小相同(或更大)的 int 是完全有效的。

于 2013-03-15T10:08:11.870 回答
0

我会在这里投票,因为通常不允许将指针分配给整数,并且会产生警告。当然使用它是一个非常好的主意intptr_t,因为它足够大。

于 2013-03-15T10:21:16.097 回答