Mabden said:
....
I still have a question as to whether an automatic pointer (in a
function, initialized by the compiler) is set to all-bits-zero or to the
address of NULL (void *(0)). If pointers are init'ed to zero as other
automatic variables are in a function, and NULL points to somewhere else
in memory aren't they different?
Automatic pointers are uninitialized unless explicitly intitialized. If
explicitly initialized, they're initialized with whatever you specified
in the explicit initialization.
Therefore, I'm going to assume you're actually talking about static
pointers. If not explicitly initialized, they are zero-initialized,
which means that they are initialized with a value of 0 converted to
the appropriate pointer type. The result of that conversion is
guaranteed to be a null pointer; it's not guaranteed to have all bits
0, and it's not guaranteed to refer to the memory location with an
address of 0 (which are two seperate issues).
I'm going to give an example as I keep getting "answers" that miss the
point, so sorry if you understand and this bores you - it bores me more
to try to explain my point a thousand times over, but here goes:
NULL is a pointer to a zero in memory at 0x11112222.
My function has a pointer that gets initialized automagically. I don't
know whether it gets init'ed to NULL (0x11112222) or all-zeros
(0x00000000). What does The Standard say?
It gets intialized with a null pointer. If the implementation provides
multiple representations for null pointers of a given type (which it is
permitted to do), then that null pointer might or might not have the
same bit pattern it would have had if it had been initialized with
NULL. However, it is guaranteed to compare equal with NULL, regardless
of whether it has the same bit pattern, because all null pointers are
guaranteed to compare equal to each other.
Now, if the automatic pointer is actually init'ed to NULL, then there is
no problem that I can see.
NULL expands into a NULL pointer constant. The result of assigning a
null pointer constant to an object of pointer type is that the pointer
will contain a representation of a null pointer. However, if an
implementation allows multiple representations of a null pointer, it's
perfectly legal for assignment of NULL to a variable to produce a
different representation of a null pointer each time it occurs.
IFF it is the second case of 0x00000000, then it seems to me that
0x00000000 != 0x11112222. Does that seem reasonable?
0x00000000 != 0x11112222, regardless of which of those two cases apply.
That's simply a matter of ordinary arithmetic applied to hexadecimal
integer literals. However, if those integers represent memory
locations, there's no guarantee that they refer to different memory
locations. I've seen real machines where the same memory location had
multiple representations.
If an implementation chooses to define pointers referring to both of
those addresses as null pointers, then those pointers must compare
equal, regardless of which location they nominally point at.
Technically, it's not meaningful to talk about which location a null
pointer points at, because there's no way within strictly conforming C
to find out anything about that location. However, an implementation
can chooses to make the undefined behavior that results from
dereferencing a null pointer, be that it acts as a normal pointer
referencing a specific memory location. Therefore, there can be an
implementation-specific meaning to the concept of where an null pointer
points at; there just isn't any portable meaning to the concept.
... In this case,
assigning the 0x00000000 to a _Bool would seem, to me, to produce a
false since it is not NULL. This is what I was saying to Flash that
turned into a lecture about NULL not being all-zeros (which is the point
I was actually making).
Assigning a null pointer value to a _Bool always results in the _Bool
variable containing the value false, regardless of what bit pattern the
pointer value is represented by, and regardless of which address that
pointer value refers to.
If they are different, and your getFoo() returns a pointer that is not
NULL, but is all-bits-zero then wouldn't storing that pointer in a _Bool
variable give a false value?
The relevant question is whether the bit pattern represents a null
pointer. It doesn't matter whether it's all-bits-zero, it doesn't
matter whether it represents an address of 0, and it doesn't matter if
the value it was most recently initalized with or that was assigned to
it wasn't NULL. All that matters is whether the result of the most
recent initialization/assignment was a null pointer. If it was, then
the _Bool value will be "false", otherwise it's true.
I believe it should, since 0x00000000 !=
0x11112222, and 0x00000000 may be a valid address in this memory space
on some hardware / software combo.
If an implementation chooses to treat a pointer to the memory address
of 0x00000000 a null pointer, and to also treat a pointer to the memory
address 0x11112222 as a null pointer, those pointers must compare equal
to all null pointers, including each other. They must both compare
unequal to any pointer to an actual object, and must both covert to
"false" in a _Bool context. That means that the implementation is
required to ensure that any objects actually located at those addresses
cannot be referred to by a C program using strictly conforming code.
However, if you used the actual pointer you would write code like this:
pFoo = getFoo();
if (pFoo && success)
{
/* actually do something with pFoo, since you went and got it... */
return true; /* or return success; */
}
else return false;
Now my understanding is that the if() would work in both cases of pFoo
being NULL or pFoo being all-zeros, is that correct?
No, for the reasons given above.
p.p.s. Please, please, please don't reply that NULL does not have to be
all-zeros...
As far as I can tell, I avoided that.
I can back up almost every statement I made above with an explicit
citation from the C standard. Ordinarily, I would include those
citations in the text, but in this case there are just too many of
them. If you find any of my assertions controversial, tell me which
ones and I'll give you the relevant citations.
Note: I don't normally monitor comp.lang.c; I came here only to
back-track some comments you made on comp.std.c. I'll watch this thread
for a day or two, but if you take longer than that to respond to this
message, it would be helpful if you send me e-mail reminding me of your
response.