我有一个结构
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;
该怎么会对运行时错误产生任何影响。它汇编得很好。但是代码的执行是我主要关注的问题。
由于
答案 0 :(得分:6)
标准中无法保证如果ptr
为空指针,则(uintptr_t)ptr
为0
。
如果你不关心空指针和零整数不相等的系统,那么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
是一个非常好的主意,因为它足够大。