Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

338
Views
When NULL is not all-zero-bits, is an all-zero-bit pointer value also 'false'?

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;
}
over 4 years ago · Santiago Trujillo
4 answers
Answer question

0

There's a great discussion of NULL and 0 in the first answer to this question: What is the difference between NULL, '\0' and 0?

The punchline in that answer is:

Note that what is a null pointer in the C language. It does not matter on the underlying architecture. If the underlying architecture has a null pointer value defined as address 0xDEADBEEF, then it is up to the compiler to sort this mess out.

…Even on this funny architecture, the following ways are still valid ways to check for a null pointer:

if (!pointer)
if (pointer == NULL)
if (pointer == 0)

And in the second answer to the same question…

A constant expression of type int with the value 0, or an expression of this type, cast to type void * is a null pointer constant, which if converted to a pointer becomes a null pointer. It is guaranteed by the standard to compare unequal to any pointer to any object or function.

(Short answer, yes, you can check for a NULL pointer with if (!ptr)).

over 4 years ago · Santiago Trujillo Report

0

typedef struct { void * p; } obj;
obj * o = calloc(sizeof(obj), 1);
assert(o);  // Let us set aside the case of a failed allocation
printf("%s\n", o->p ? "true" : "false");  // 1st: could print "true" ?

can I rely on calloc to produce a pointer value that will always evaluate to false in boolean contexts/comparisons?

No - output could be "true".*1.

The bit pattern of all zeros, as a pointer, may not be a null pointer.

7.22.3.2 The calloc function
2 The calloc function allocates space for an array of nmemb objects, each of whose size is size. The space is initialized to all bits zero.301)
Footnote 301) Note that this need not be the same as the representation of floating-point zero or a null pointer constant.


Example: An implementation may only have only a single null pointer encoding with a bit pattern of all ones. (void *)0 converts the all zeros bit pattern int 0 to an all ones void *. if (null_pointer) is always false, regardless of the bit pattern of the null pointer.


*1 Yet practically yes, output is always "false". Implementations are uncommon these days that do not use all zero bit pattern as a null pointer. Highly portable code would not assume this practicality. Consider an old or new novel system may use a zero bit pattern as a non-null pointer - and sadly break many a code base that assumes an all zero bit pattern is a null pointer.

over 4 years ago · Santiago Trujillo Report

0

Core Answer

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 a C implementation, the C standard allows any of:

  • All-bits-zero is a null pointer and no other bit pattern is.
  • All-bits-zero is a null pointer and one or more other bit patterns are.
  • All-bits-zero is not a null pointer and one or more other bit patterns are.

In other words, a C implementation may designate any one or more bit patterns to be null pointers, and this may or may not include all-bits-zero. (If the C implementation does allow multiple bit patterns to be null pointers, it must ensure they compare equal.)

… will the 1st printf in the program below ever output true?

It is allowed that it print “true”; the result of calloc is memory with all bits zero, and interpreting that memory as a void * may result in a pointer value that is not a null pointer value.

Supplement

… where NULL is *not* all zeros…

NULL is only something in source code. It is either 0 or ((void *) 0) or an equivalent. Wherever it is used as a pointer in source code (that is, you are doing normal things like if (pointer != NULL), not kludges like int x = 3 + NULL;), the compiler effectively converts it to a null pointer. That is, if all-bits-zero is not a null pointer in the C implementation, the compiler will compile pointer != NULL to a comparison of pointer to some bit pattern that does represent a null pointer.

So your questions are all about null pointers; they are not about NULL.

… on systems where…

The final determination of what is a null pointer lies with the C implementation, not the system it executes on. A C implementation may represent pointers in any way it wants and transform them as necessary when using machine addresses in instructions.

over 4 years ago · Santiago Trujillo Report

0

You can avoid such questions with an explicit and defensive coding style.

if you have an pointer _p, write constructs like

    (_p==NULL)?(A):(B)

now any reader knows immediately, your intend is to check if _p is equal to NULL and even on a machine where NULL might be different from an integer value of 0, the compiler will automatical do it correctly. Also an static code checker now will not warn you because of relying on implicit behaviour.

    (_p)?(A):(B)

is just not doing it right

but apart from that, its an interesting technical question.

A interesting Talk from the C++ committee from 2019 or 2020 revealed that even these guys think about dropping compatibility to some odd undefined behaviour, which was needed back before 1970 for some 3-4 architectures. There wasn't any known use of this stuff in the last decades - at least to my knowlege. As the first comment to your questions states: You will hardly find any machine with such an issue - at least outside of an museum.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!