tags:

views:

110

answers:

2

As per my knowledge, all occurrences of NULL in code are replaced by a 0 during the preprocessing stage. Then during compilation, all occurrences of 0 in pointer context are replaced by an appropriate value which represents NULL on that machine. Thus the compiler has to know that NULL value for that particular machine.
Now, this means that whenever I use 0 in pointer context, it is replaced by the appropriate value representing NULL on that machine, which may or may not be 0. So, how can I tell the compiler that I actually mean 0 and not NULL, when I use 0 in pointer context?
Sorry for the long description. Correct me if I am wrong

+4  A: 

One way is to store all-bits-zero into your pointer:

void* zero;
memset(&zero, 0, sizeof(zero));
Rob Kennedy
neat trick - except on most systems this is gonna go bang when he goes *zero. Unless he is lucky enough to work on a machine with non zero NULL (As I used to; NULL was 0xffffffff so you could happily do *zero and see what lived at address 0)
pm100
Right. On *most* systems, using `memset` like this is pointless because you'll get the same result from simply assigning `zero = NULL` — the zero address and the null pointer are the same thing. But when zero isn't the null pointer *and* you need to hard-code the address in your program, this can be useful.
Rob Kennedy
+3  A: 

Well, there's no portable way to achieve that in C. C language provides no portable features specifically intended for aiming a pointer to a specific numerical address. However, the "secret" intent of the explicit integer-to-pointer conversion is actually just that: to implement the "natural" mapping between the integers and pointers, where "natural" normally means that the numerical value of the integer is preserved intact (if possible) when converting it to pointer type. In other words, all you need is an integer with 0 value. You just need to make sure that this integer does not qualify as an Integral Constant Expression, since otherwise it will be recognized as null-pointer constant. (In simple terms, you need a run-time integral zero, not a compile-time integral zero).

For example, this

uintptr_t i = 0;
void *p = (void *) i;

will normally produce a pointer pointing to address 0. Moreover, in C language (as opposed to C++) this

const uintptr_t i = 0;
void *p = (void *) i;

will also normally produce a pointer pointing to address 0. While this

void *p = 0; /* compile-time 0 will not do */

will produce the implementation-specific null-pointer value.

You can also take a look at C FAQ here, which covers this very issue.

AndreyT