在C中类推NULL指针

时间:2013-03-15 10:00:48

标签: c windows struct null

我有一个结构

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;该怎么会对运行时错误产生任何影响。它汇编得很好。但是代码的执行是我主要关注的问题。

由于

3 个答案:

答案 0 :(得分:6)

标准中无法保证如果ptr为空指针,则(uintptr_t)ptr0

如果你不关心空指针和零整数不相等的系统,那么info.init = 0;就可以了。

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

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

因此,如果你想保证info,当转换为指针类型时,会产生一个空指针,然后为了真正的可移植性,你应该info.init = (uintptr_t)(void*)(NULL);。您可以选择通过包含uintptr_t将要转换为的指针类型而不是void*来为读者提供额外的线索。存储uintptr_t的原因很少,因此提示正在发生的事情可能有助于读者。

请注意,标准中保证转换为指针类型的零值常量表达式是空指针。这意味着转换为指针类型的零值非常量表达式是空指针。它也不意味着转换为整数类型的空指针为0.在大多数实现中,最后两件事情都是正确的(包括所有"现代" 1)。

答案 1 :(得分:3)

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

答案 2 :(得分:0)

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