5

Are there any ANSI C conforming environments where all-bits-zero is not a representation for a null pointer? 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.

1
  • Comments are not for extended discussion; this conversation has been moved to chat. Commented Oct 7, 2022 at 2:52

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

12 Comments

Thank you for your answer but at the risk of being misunderstood, to add some context for my question, the motivation for my question is rooted in why the C standards committee would (1) allow ptr=0 to set null pointers, but at the same time (2) not require that null pointers be all zero bits. If supporting platforms with non-zero bit null pointers was important, why require (1) to make implementation more awkward for compiler writers and users of such platforms when requiring users to use NULL could work just fine?
@I'm sorry, but this is all very, very old ground, about which far too many redundant words have been written. Please read all of section 5 in the C FAQ list, and if you still have a question, get back to me. (Also, when you get to question 5.14, note that C++ has now added a nullptr keyword, although IMO they botched it. )
many of them actually had non-zero NULL macros as well I believe this to be 100% false. #define NULL 0 has always worked perfectly well on a machine with nonzero null pointers.
@math4tots When C was new, the C preprocessor was even newer, and it was optional, not trusted/used by all programmers. But knowledge of those "really old platforms" (which weren't so old then) was more widespread. So p = 0 was a totally official way to get a null pointer, even if the bit pattern wasn't 0. But this isn't — or shouldn't be — surprising! float f = 0 gets you a machine-dependent bit pattern that might not be all-bits-0. For that matter, saying a = b + c gets you a machine-dependent opcode for the + operator.
It's the compiler's job to generate the machine-dependent bits for the higher-level constructs you write. Just about all of the confusion surrounding null pointers in C flows from Dennis Ritchie's decision to use 0 as the keyword for "null pointer" instead of something like nullptr. Using 0 unfortunately invites false assumptions.
|
3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.