Home > OS >  ANSI C conforming platforms where the null pointer representation is not all-bits-zero
ANSI C conforming platforms where the null pointer representation is not all-bits-zero

Time:10-04

Are there any ANSI C conforming environments where the representation for the null pointer (not the null pointer constant) is not all-bits-zero? That is, environments where the following program would print 0? If so, can you list some examples?

#include <string.h>
#include <stdio.h>

struct MyStruct {
  void *somePointer;
};

int main() {
  struct MyStruct ms;
  memset(&ms, 0, sizeof(ms));
  printf("%d\n", ms.somePointer == 0);
}

NOTE: There's some nuance here, but I'm afraid if I try to elaborate, too many people who don't carefully read the question will misunderstand and think it's similar to so many questions related to null pointers that has been asked.

CodePudding user response:

It seems no POSIX compliant system would nor should output 0.

Eric Blake raised this issue in 2015 and the POSIX text was amended in 2020 by Geoff Clare to reflect that all bits zero should always be treated as a null pointer.

Read the report here: https://www.austingroupbugs.net/view.php?id=940

This is only a partial answer, as non POSIX compliant systems could still be C90 compliant and output 0. Yet such systems would cause a lot of headaches to programmers trying to port software that quietly relies on all bits zero being a valid representation of null pointers. It is quite common for structures to be allocated with calloc() and many programmers silently assume that all members of such structures are initialized to 0, which is correct for integers, but not guaranteed for floating point types (albeit true for IEEE-754 compliant systems) nor for pointer types.

CodePudding user response:

Here are three examples of computers which have used something other than all-bits-0 for null pointers:

  • the Prime 50 series
  • the CDC Cyber 180 Series
  • some Honeywell-Bull mainframes

I can't say whether there are or were ever ANSI C compilers for these machines, however.

For further details, see question 5.17 in the C FAQ list.


Addendum: I suspect there are really two questions here:

  1. Have there actually ever been machines with nonzero null pointers?
  2. Is it safe in 2022 to write memset(&ms, 0, sizeof(ms)), as in the example in this question, and expect pointer values like ms.somePointer to come out as proper null pointers?

The answer to question 1 is undeniably "yes". (The question becomes less clear, though, if we change "Have there actually ever been" to "Are there".)

The answer to question 2 is, I think, still a matter of opinion. My own answer would be "Yes, it's safe, although I wouldn't do it, unless I was in a big hurry." That is, after memsetting all my newly-allocated C structs to 0, I still like to explicitly set any pointer fields to NULL.

But I think this is the sort of thing that every project needs to decide for itself, as part of its overall style/best practices guide. For certain issues like this one, it's still unfortunately somewhat of a judgement call whether to say "Thou shalt write 100% strictly conforming C code always", versus "We accept this practice, even though it may not be 100% strictly conforming, because we believe it should work everywhere, on any reasonable platform we care about."

Many times, saying "I believe this practice, though not guaranteed to work, should work on any reasonable platform" is quite perilous. But sometimes, it's perfectly reasonable. As I said, it can be a judgement call.

  • Related