I know C compilers aren't required to use all zeros for the bit representation of NULL, but they *are* required by the standard to make NULL evaluate to false in boolean contexts/comparisons. Hence the 2nd printf in the program below will always output false.
But what I want to know is: on systems where NULL is *not* all zeros, will a pointer value that *is* all zeros also evaluate to false in boolean contexts/comparisons? In other words, will the 1st printf in the program below ever output true?
Or asked in a slightly different way: can I rely on calloc to produce a pointer value that will always evaluate to false in boolean contexts/comparisons? The 1st answer to this question uses memset to clear the bits of a long* named y, then goes on to say that y==0 is UB because y may be a "trap representation" (whatever that is). calloc is also just clearing bits, so maybe o->p in the 1st printf is also UB?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct { void * p; } obj;
int main() {
obj * o = calloc(sizeof(obj), 1);
assert(o); // assume successful allocation
printf("%s\n", o->p ? "true" : "false"); // 1st: could print "true"? Is o->p UB?
o->p = NULL;
printf("%s\n", o->p ? "true" : "false"); // 2nd: always prints "false"
return 0;
}