Reputation: 761
I have a structure
struct detail {
int id;
uintptr_t init;
// blah blah
};
struct detail info;
info.id = 1;
info.init = (uintptr_t)NULL;
I have to make the the init
member NULL. What may/may not happen if I typecast(or do not typecast) NULL
? What if I directly assign it NULL like info.init = NULL;
Does it make any difference with respect to runtime errors. It compiles fine. But the execution of the code is my main concern.
Thanks
Upvotes: 6
Views: 4542
Reputation: 279395
There is no guarantee in the standard that if ptr
is a null pointer, then (uintptr_t)ptr
is 0
.
If you don't care about systems on which null pointers and zero integers aren't equivalent, then info.init = 0;
is fine.
The init
member has integer type, it cannot be "made null". You can assign 0
to it, or you can assign to it the result of converting a null pointer to uintptr_t
. On almost every C implementation ever, those are the same thing. But it is not guaranteed, and there have been systems on which it is not the same.
NULL
might be a null pointer, or it might be an integer constant 0
. In the latter case, there is a guarantee in the standard that (uintptr_t)(NULL)
is 0
. So there can be implementations on which info.init = NULL; (void*)(info.init);
has undefined behavior. It wouldn't result in a null pointer if the integer equivalent of null isn't 0, and computing an invalid pointer value is UB.
So, if you want to guarantee that info
, when converted to a pointer type, results in a null pointer then for true portability you should do info.init = (uintptr_t)(void*)(NULL);
. You could optionally give the reader an extra clue by including the pointer type that the uintptr_t
is going to be converted to, instead of void*
. There are very few good reasons for storing a uintptr_t
, so hints what is going on might help the reader.
Note that there is a guarantee in the standard that a zero-valued constant expression, converted to pointer type, is a null pointer. This does not imply that a zero-valued non-constant expression, converted to a pointer type, is a null pointer. Neither does it imply that a null pointer, converted to integer type, is 0. Those last two things happen to be true in most implementations (including all "modern" ones).
Upvotes: 8
Reputation: 400109
I would vote for the cast here, since assigning pointers to integers is generally not allowed and will generate a warning. It's a very good idea to use intptr_t
of course, since it's big enough.
Upvotes: 0
Reputation: 3588
NULL is a built in constant with a value matching whatever a null pointer is on your system. It's perfectly valid to assign the constant value to an int the same size (or bigger) than a pointer on your system.
Upvotes: 2