Null pointers

D

Default User

Mabden said:
Fools are always brave; it goes with the territory. And Brian assures me I
am a fool (thanks for that Brian, I think the world of your people skills
and I'm sure you have many loving friends).

Please quote some post where I called you a fool. I don't believe I did
anything of sort, or even came close to it.



Brian Rodenborn
 
M

Malcolm

Mabden said:
NULL is a macro, I agree, for basically (char *)0.
If you look in your standard headers, you could easily find the line
#define NULL ((void *) 0)
My point was that null, ie: 0:0, is considered an invalid location for data.
Furthermore, I believe it is "guaranteed" to be invalid for data in C.
It is not guaranteed by the standard.
In practical terms, malloc() will never return a pointer with all bits zero,
and no item in the stack or in global memory will be all bits zero either.
This is because the lowest location in memory is always special in some way,
and even if it wasn't it would be natural to use all bits zero for the null
pointer.
However this doesn't necessarily mean that you cannot force a pointer to be
all bits zero, and then read and write to it. For instance if the lowest
address in memory happens to be used by a fast machine instruction, but is
left spare by the compiler, then storing an integer in it could merely hog a
slot that an assembly programmer could put to better use. It won't
necessarily prevent the program from working.
 
M

Michael Wojcik

[re K&R2 p 120]

From the context it's clear that in this instance they're referring to
a pointer value - what's returned by their alloc() function. However,
the text fails to make clear that this does not apply to the actual
internal representation of an address. The use of "address" here is
infelicitous - it's either wrong or misleading. IMO this should be
added to the errata list.

That may be so but let us not be hasty.

Nor was I, when I composed that message.
Here are some passages from C99.

Indeed they are, and they agree with me. If you feel they do not,
perhaps you should have explained why, rather than merely quoting
them without comment.
 
R

Richard Tobin

Mabden said:
And my point is that the one, true null pointer, regardless of hardware is
location 0:0 in memory on whatever architechure you use.

The idea that addresses consist of a segment and offset is just a
feature of some architectures. Even on the most common architecture
that uses that feature - the x86 - most current operating systems
provide a linear address space in which segments are irrelevant to
almost all programmers.

-- Richard
 
M

Mabden

Richard Bos said:
Mabden said:
Keith Thompson said:
So, you are saying that (on some mythical machine) I could have an
array a[] that lives at location 0000:0000 of memory and point to it
with ptr = &a and ptr would not be a NULL pointer?

The very fact that you have an array at that location means that it
cannot possibly be a null pointer; the null pointer is guaranteed not
ever to point at any object.
That is what I mean, yes, as it was a popular notion in Windows programming
denoting segment:eek:ffset. I will use "null" to mean location 0 in memory
(0000:0000, or 0:0 for short), as in the very first addressable location
possible on the machine.

Then you still do not get it. Null pointers _need not_ point to the
lowest existing location in memory.

Of course I get that they don't "need" to point to location zero. Do you
understand that? I gave an example where NULL was pointing to 0x12344321. I
get that. NULL or null pointer or whatever does not need to point at
location zero. See, I get it. That's not my point.

My point is that in addition to the NULL or null of whatever you want to
call the thing, separately, and different from that issue, is that location
zero in memory should not be able to store data in a C program.

And assuming a prat is a bad thing to be, I'll have to say you seem like as
well, for your constantly turning the argument off-course with all the
harping on the null pointer issue which we all agree on, even me.
 
M

Mabden

Richard Tobin said:
The idea that addresses consist of a segment and offset is just a
feature of some architectures. Even on the most common architecture
that uses that feature - the x86 - most current operating systems
provide a linear address space in which segments are irrelevant to
almost all programmers.

No kidding. It is just a way of expressing location zero in memory, as I
explained in the bit you snipped. I am not talking about any particular
architecture. I am talking about any machine that runs a C program.
 
R

Richard Tobin

Mabden said:
No kidding. It is just a way of expressing location zero in memory, as I
explained in the bit you snipped.

In a segmented architecture, "location zero" may not mean anything at
all. In a non-segmented architecture, "0:0" is meaningless. You're
just used to x86s and think it's a natural notation, when in fact it's
completely architecture-specific.

-- Richard
 
C

Christian Bau

"Mabden said:
Of course I get that they don't "need" to point to location zero. Do you
understand that? I gave an example where NULL was pointing to 0x12344321. I
get that. NULL or null pointer or whatever does not need to point at
location zero. See, I get it. That's not my point.

My point is that in addition to the NULL or null of whatever you want to
call the thing, separately, and different from that issue, is that location
zero in memory should not be able to store data in a C program.

There is nothing special about location 0, or location 1, or location 2,
or location 3 and so on and so on.

In many C implementations, any hardware pointer that the implementation
could use must point _somewhere_, so the location that a null pointer
points to would be special in that it cannot be used for holding C
objects. But for example on an 80286 implementation using segmented
pointers, the null pointer would most likely be represented by a segment
of 0 and an offset of 0, and on that hardware this combination doesn't
point _anywhere_. Not only does a null pointer not point to any C
object, it doesn't point anywhere at all.
 
O

Orhan Kavrakoglu

p ^= p; /* illegal */
Here's a cleaner way to do what you're trying to do:
memset(&ptr, 0, sizeof(ptr));

*smack on the forehead*

Yeah, that's what I meant. I know the xor operation is illegal on
pointers, but I couldn't think of memset. Let's see now, 999 more
smacks on the forehead before I can explain hypothetical situations
with legal code.
 
K

Keith Thompson

Malcolm said:
In practical terms, malloc() will never return a pointer with all
bits zero, and no item in the stack or in global memory will be all
bits zero either. This is because the lowest location in memory is
always special in some way, and even if it wasn't it would be
natural to use all bits zero for the null pointer.

As you know, malloc() will return a pointer with all bits zero if the
allocation fails and that happens to be the representation of a null
pointer.

Having said that, you're assuming that all-bits-zero is the lowest
location in memory. If addresses are treated as signed integers,
all-bits-zero is right in the middle of the address space, and it's
quite likely that something could be allocated there. (I have no idea
whether this applies to any real systems.)

In any case, 99+% of the time there's no need to care about whether a
particular address is all-bits-zero or not -- and if you do care, then
you're doing some very system-specific stuff and you'd better know
exactly what you're doing.
 
K

Keith Thompson

Mabden said:
Of course I get that they don't "need" to point to location zero. Do you
understand that? I gave an example where NULL was pointing to 0x12344321. I
get that. NULL or null pointer or whatever does not need to point at
location zero. See, I get it. That's not my point.
Great.

My point is that in addition to the NULL or null of whatever you want to
call the thing, separately, and different from that issue, is that location
zero in memory should not be able to store data in a C program.

You're simply wrong about this. Read the reference section (Appendix
A) of K&R2. Read the FAQ, particularly section 5. If you don't have
a copy of the actual C standard, read the relevant portions of the
latest public draft (Google "n869"). Or if you're unwilling to do
that, just listen to the rest of us, who do actually know what we're
talking about.

As you know, the null pointer may or may not be all-bits-zero. As
you've so far refused to acknowledge, the C language says nothing in
particular about an all-bits-zero address; if it's not a null pointer,
it could easily be the address of an object. The only basis for
believing otherwise is a vaguely worded (and arguably incorrect)
sentence on page 102 of K&R2.

BTW, I had forgotten until recently about my previous encounters with
you in this newsgroup. As of just a couple of months ago, you were a
deliberate, self-admitted troll. It's hard to avoid the conclusion
that you haven't changed much. Do you honestly believe that an
all-bits-zero address is somehow special, or are you just trolling
again? (That's a serious question.)
 
J

junky_fellow


Just one more doubts that i wanted to clarify ....
Consider all-bits-zero a valid address on some machine, and address
0x12345678 represents null pointer.

i have three pointers,
char *ptr1, *ptr2, *ptr3;
ptr1 = NULL; // (null pointer).
ptr2 = (char *)malloc(sizeof(char)); /* and the address returned by OS is 0x0
which is a valid address, i.e ptr2 is
pointing to location 0x0 (all-bits-zero)*/
ptr3 = (char *)0x12345678; /* deliberate assignment to some address */

Now if i compare pointers, (ptr1 == ptr2) what would be the result ?
Theoretically, they shouldn't be equal.

and if i compare (ptr1 == ptr3) what would be the result ?
 
R

Richard Bos

Malcolm said:
If you look in your standard headers, you could easily find the line
#define NULL ((void *) 0)

You don't know that - it is also reasonably likely to be #defined as a
naked 0, and may, but highly probably isn't, be defined as something as
silly as ('-'-'-').
It is not guaranteed by the standard.
In practical terms, malloc() will never return a pointer with all bits zero,

You don't know that.
and no item in the stack or in global memory will be all bits zero either.

You don't know that.
This is because the lowest location in memory is always special in some way,

You don't know that.
and even if it wasn't it would be natural to use all bits zero for the null
pointer.

Not if there is another natural invalid pointer on the system, it
wouldn't.

Not all the world is a Wintel box. Not nearly all the world, in fact.

Richard
 
C

Christian Bau

i have three pointers,
char *ptr1, *ptr2, *ptr3;
ptr1 = NULL; // (null pointer).
ptr2 = (char *)malloc(sizeof(char)); /* and the address returned by OS is 0x0
which is a valid address, i.e ptr2 is
pointing to location 0x0
(all-bits-zero)*/
ptr3 = (char *)0x12345678; /* deliberate assignment to some address
*/

Now if i compare pointers, (ptr1 == ptr2) what would be the result ?
Theoretically, they shouldn't be equal.

and if i compare (ptr1 == ptr3) what would be the result ?

Keep in mind that cast from int to char* is "implementation defined" and
doesn't necessarily give a useful result, so if you have a variable "int
x" then "(char *) x == NULL" could be true for many different values of
x.

When you use a cast to convert say from int to float, the bits don't
stay unchanged: int i = 1; float f = (float) i; will produce very
different representations in i and f even though both are equal to one.
Same with a cast to convert from int to char*. Now typically compilers
where a null pointer has an all-bits-zero representation will leave the
representation unchanged, but if a null pointer has the same
representation as 0x12345678 then that would be no good. You would
expect that cast from int to char* will be implemented with machine code
that would map (all bits zero) to the same bit pattern as 0x12345678. It
might add 0x12345678, it might do an xor with 0x12345678. A useful
implementation would try to achieve that (char *) (int) p == p, as long
as sizeof (int) is large enough to hold a pointer. So I would expect
ptr3 and ptr2 to compare not equal.
 
M

Mabden

Keith Thompson said:
You're simply wrong about this. Read the reference section (Appendix
A) of K&R2. Read the FAQ, particularly section 5. If you don't have
a copy of the actual C standard, read the relevant portions of the
latest public draft (Google "n869"). Or if you're unwilling to do
that, just listen to the rest of us, who do actually know what we're
talking about.

As you know, the null pointer may or may not be all-bits-zero. As
you've so far refused to acknowledge, the C language says nothing in
particular about an all-bits-zero address; if it's not a null pointer,
it could easily be the address of an object. The only basis for
believing otherwise is a vaguely worded (and arguably incorrect)
sentence on page 102 of K&R2.

BTW, I had forgotten until recently about my previous encounters with
you in this newsgroup. As of just a couple of months ago, you were a
deliberate, self-admitted troll. It's hard to avoid the conclusion
that you haven't changed much. Do you honestly believe that an
all-bits-zero address is somehow special, or are you just trolling
again? (That's a serious question.)

I am not trying to be a troll, altho I do occasionally poke fun at the risk
of being called one.

I'm sorry it may seem that way in this thread, but I have to keep repeating
myself because everyone is running of the mouth about null pointer !=
0x00000000. It is not very pleasant for me to have to keep repeating myself,
and I'm pretty much done now, as I've said my piece and I believe a few
people understand what I'm saying - they don't agree, call me idiot and
prat, etc. but they get my point. I believe you are one of those.

It's actually a silly argument, and I believe it has only gone on this long
because everyone thinks I don't realize that (char *)0 is not at location
zero. I do, and it's not what I'm saying. But you get my point and you say
I'm wrong, which is fine. You haven't been rude (that I recall), which I
also appreciate! So I think we can drop this now. I will just state my
opinion on the issue one last time, but no need to reply, I just want to
wrap up my point one last time.

<opinion>
I am talking about the pg 102 reference, which people are saying is
incorrect or just plain wrong. I don't think it is, or should be.
Apparently, the various Standards (I don't have a copy) is a little vague
about the concept or someone would tell this or that page says location zero
is valid. I, however, take that little snippet in K&R2 as a very easy to
understand concept, and I believe it should be enforced by a compiler.

So regardless what the Standard says, or is, I still believe there should be
(not IS, _should be_) an ultimate place that is NOT implementation defined,
at is always true across all versions of C that can never be used for
storage. A magic location that will fail if you write to it or read from it.
Since we cannot know the largest memory location, why not use the smallest:
0. I also think this concept is hinted at on K&R2 pg 102.
</opinion>

p.s. If, in the future, I say, "Zero is never a valid location..." it is NOT
meant to reopen this argument or troll. It is just an ingrained, knee-jerk
reaction, like saying, "Bless you!" when someone sneezes. Apologies in
advance.
 
C

Chris Dollin

Keith said:
Having said that, you're assuming that all-bits-zero is the lowest
location in memory. If addresses are treated as signed integers,
all-bits-zero is right in the middle of the address space, and it's
quite likely that something could be allocated there. (I have no idea
whether this applies to any real systems.)

Do transputers count? I believe they had signed addressing.
 
K

Keith Thompson

Mabden said:
I am not trying to be a troll, altho I do occasionally poke fun at the risk
of being called one.

Ok, thanks for the clarification (seriously).
I'm sorry it may seem that way in this thread, but I have to keep repeating
myself because everyone is running of the mouth about null pointer !=
0x00000000. It is not very pleasant for me to have to keep repeating myself,
and I'm pretty much done now, as I've said my piece and I believe a few
people understand what I'm saying - they don't agree, call me idiot and
prat, etc. but they get my point. I believe you are one of those.

Yes. (I don't think you're an idiot, just mistaken.)

BTW, in the above paragraph you've just added to the confusion. You
say "null pointr != 0x00000000", but if 0x00000000 is meant to be a C
integer constant, it's a null pointer constant which, when converted
to a pointer type, yields a null pointer. Again, that's why I've been
very careful to use the phrase "all-bits-zero" rather than something
like 0x00000000.

Assuming that all-bits-zero is a null pointer is a common
misconception. Since you clearly misunderstand some aspects of the
relationship between null pointers and various meanings of "zero",
it's easy to assume that you share the more common misconception and
aren't expressing it very well. I think that's why you've needed to
repeat yourself. Apparently you've managed to come up with a brand
new misconception (at least I had never heard of it before) and, after
going back and forth a few times, are expressing it reasonably
clearly.
It's actually a silly argument, and I believe it has only gone on this long
because everyone thinks I don't realize that (char *)0 is not at location
zero.

.... is not *necessarily* at location zero.
I do, and it's not what I'm saying. But you get my point and you say
I'm wrong, which is fine. You haven't been rude (that I recall), which I
also appreciate! So I think we can drop this now. I will just state my
opinion on the issue one last time, but no need to reply, I just want to
wrap up my point one last time.

<opinion>
I am talking about the pg 102 reference, which people are saying is
incorrect or just plain wrong. I don't think it is, or should be.
Apparently, the various Standards (I don't have a copy) is a little vague
about the concept or someone would tell this or that page says location zero
is valid. I, however, take that little snippet in K&R2 as a very easy to
understand concept, and I believe it should be enforced by a compiler.

The standard is not at all vague about this. There is no page in the
standard that says zero is a valid location, because it isn't
necessarily a valid location. Nobody is claiming that all-bits-zero
is *always* a valid address. Nobody other than you is claiming that
all-bits-zero is *never* a valid address. What the standard says
about an all-bits-zero address is the same as what it says about an
all-bits-one address, or an address represented as 0xdeadbeef --
nothing.

Appendix A of K&R2 is a reasonably good reflection of the information
in the standard. Read it.
So regardless what the Standard says, or is, I still believe there
should be (not IS, _should be_) an ultimate place that is NOT
implementation defined, at is always true across all versions of C
that can never be used for storage. A magic location that will fail
if you write to it or read from it. Since we cannot know the
largest memory location, why not use the smallest: 0. I also think
this concept is hinted at on K&R2 pg 102.
</opinion>

If you want to require attempts to write to or read from the
all-bits-zero address to fail, you'll render a number of real-world
systems non-conforming.

<opinion>
Different platforms have different pointer representations. A given
bit pattern representing a valid or invalid address on one system has
no relationship to the same bit pattern representing a valid or
invalid address on another system. It makes no sense to impose any
meaning on one particular bit pattern across all platforms. And since
each platform has a well-defined unique pointer value that denotes no
object (the null pointer), there is simply no need for a second such
value (all-bits-zero).
</opinion>

As for page 102 of K&R2, when I have my copy in front of me I'll send
an e-mail message to Dennis Ritchie and ask for a clarification. I'll
let you know what he says.
 
K

Keith Thompson

Christian Bau said:
Keep in mind that cast from int to char* is "implementation defined" and
doesn't necessarily give a useful result, so if you have a variable "int
x" then "(char *) x == NULL" could be true for many different values of
x.

When you use a cast to convert say from int to float, the bits don't
stay unchanged: int i = 1; float f = (float) i; will produce very
different representations in i and f even though both are equal to one.
Same with a cast to convert from int to char*. Now typically compilers
where a null pointer has an all-bits-zero representation will leave the
representation unchanged, but if a null pointer has the same
representation as 0x12345678 then that would be no good.

I'm going to use the notation $12345678$ to refer to a pointer whose
internal representation is the same as the integer 0x12345678.

Even an implementation with the null pointer represented as
$12345678$, integer to pointer conversions could still leave the bits
unchanged, except in the case of converting a null pointer constant to
a pointer type. Remember that a null pointer constant is a source
construct, and the conversion of a null pointer constant to a pointer
value takes place during compilation. There's no requirement to
duplicate that conversion at run time.

So we could have:

(char*)0 --> $12345678$ (null pointer)
int zero = 0;
(char*)zero --> $00000000$ (non-null pointer)
(char*)0x12345678 --> $12345678$ (happens to be a null pointer)
 
M

Mabden

I'm trying to let it go, but you just keep baiting me...

Keith Thompson said:
Assuming that all-bits-zero is a null pointer is a common
misconception. Since you clearly misunderstand some aspects of the
relationship between null pointers and various meanings of "zero",
it's easy to assume that you share the more common misconception and
aren't expressing it very well.

I just haven't stated my point correctly using lawyer-like, perfect
semantics.

Now Keith, I was enjoying the fact that you didn't start assuming ignorance
on my part because you don't agree with my opinion, but you are skating
really close to the line here.

I know all about zero, pointers, etc. My opinion about location zero is not
due to any ignorance in programming C - although I have freely admitted I do
not own a copy of any "Standards" documents other than K&R and K&R2.
I think that's why you've needed to
repeat yourself. Apparently you've managed to come up with a brand
new misconception (at least I had never heard of it before) and, after
going back and forth a few times, are expressing it reasonably
clearly.

Well, then, you admit I am creative, if nothing else. Brand new? You mean
nobody else read the K&R? K&R is known to be subtle and I think this is
merely an overlooked sentence that the "Standard" has ignored for their own
purposes. Can you point me to a web site that discusses whether location
zero should be considered a special case? I think it should. Why do you have
to argue so fiercely against this idea? Are you on the Standards committee?
Am I a C heretic?

Even if I am wrong-headed, isn't it still true that location zero cannot be
written to or read from on YOUR machine. I assume you write C programs, so
just do it and tell me I'm wrong!

All my critics, please just write a simple program to read from location
zero in memory. I you can do it, post what you find there.

That's simple, isn't it?
... is not *necessarily* at location zero.

Christ, you really are a semantics nitpicker. Yes, not "necessarily" at
zero. Do you want this thread to end or are YOU the troll?
The standard is not at all vague about this. There is no page in the
standard that says zero is a valid location, because it isn't
necessarily a valid location. Nobody is claiming that all-bits-zero
is *always* a valid address. Nobody other than you is claiming that
all-bits-zero is *never* a valid address.

I am saying it *should not be* a valid address. IN MY OPINION.
I am not saying that any machine or any compiler or any standard does this.
I am stating that this is how *it should be*.
If you want to require attempts to write to or read from the
all-bits-zero address to fail, you'll render a number of real-world
systems non-conforming.

Name one.
<opinion>
Different platforms have different pointer representations. A given
bit pattern representing a valid or invalid address on one system has
no relationship to the same bit pattern representing a valid or
invalid address on another system. It makes no sense to impose any
meaning on one particular bit pattern across all platforms. And since
each platform has a well-defined unique pointer value that denotes no
object (the null pointer), there is simply no need for a second such
value (all-bits-zero).
</opinion>

OK, now that's the first response I've had that wasn't insulting or pedantic
or (in my view) wrong. You take my point and respond appropriately. It only
took 50 posts or so to get a legitimate argument. This is the reason I
decided to respond again, after giving up.

I'm not sure how you can know that "each platform has a well-defined unique
pointer value that denotes no object (the null pointer)". What is that value
on the Palm OS? What did NeXT use?
As for page 102 of K&R2, when I have my copy in front of me I'll send
an e-mail message to Dennis Ritchie and ask for a clarification. I'll
let you know what he says.

I assume that is sarcasm? I would LOVE to know what the R thinks, if you can
do that. I suspect it was a joke, and the rest of use emoticons to make that
clear, so a ;-) would have been appropriate.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,786
Messages
2,569,625
Members
45,320
Latest member
icelord

Latest Threads

Top