Null pointers

P

pete

Orhan said:
<snip>

This is only because 0 is converted to the internal value for
representing a NULL-pointer, isn't it?

Hmm let's see, how could we...

char *ptr = 0; /* ptr is a NULL pointer */
char **p = &ptr;

*p ^= *p; /* I am hoping to have cleared every bit of ptr */

If every bit of ptr is cleared and it has the value '0', it is no
longer necessarily a NULL pointer, is it?

(*p) is an expression of type pointer to char.
Bitwise operations are undefined on pointer types.

int main(void)
{
char *ptr = 0;/* ptr is a null pointer */
size_t n = sizeof ptr;

while (n--) {
((unsigned char*)&ptr)[n] = 0;
}
/*
** The bits of ptr are cleared and it's value is undefined,
** it is no longer necessarily a null pointer.
*/
return 0;
}
 
K

Keith Thompson

Orhan Kavrakoglu said:
<snip>

This is only because 0 is converted to the internal value for
representing a NULL-pointer, isn't it?

Right. (It's more accurate to say "null pointer"; NULL is a macro
that expands to a "null pointer constant", and it exists only in
source.)
Hmm let's see, how could we...

char *ptr = 0; /* ptr is a NULL pointer */
Right.

char **p = &ptr;

*p ^= *p; /* I am hoping to have cleared every bit of ptr */

There's not much point in creating something that points to ptr. The
above might as well be written as:

char *ptr = 0;
p ^= p; /* illegal */

but that's still incorrect. You can't apply the bitwise xor operator
to a pointer.
If every bit of ptr is cleared and it has the value '0', it is no
longer necessarily a NULL pointer, is it?

Correct (though it will be on many implementations).

Here's a cleaner way to do what you're trying to do:

#include <string.h>
...
char *ptr = 0;
/*
* ptr is a null pointer
*/
memset(&ptr, 0, sizeof(ptr));
/*
* ptr is all-bits-zero; it may or may not be a null pointer
*/
 
M

Mabden

Default User said:
I don't know why he keeps saying that. I explained all this to him once
on CLC++, but the message didn't get across.

He needs to engage his brain.

Brian Rodenborn

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).

<engaging brain, opening mouth, foot at the ready...>
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? I'm not sure I can get behind that. If
nothing else, the compiler (or linker or loader, whatever) should disallow
storing at memory location 0.

Also, you are saying that 0 can live anywhere in memory and ptr = 0 (as in
char *ptr = 0) would be NULL. This part I get, and agree with.
<disengaging overheated gears, cooling with beer>
 
R

RCollins

Mabden said:
I don't know why he keeps saying that. I explained all this to him once
on CLC++, but the message didn't get across.

He needs to engage his brain.

Brian Rodenborn


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).

<engaging brain, opening mouth, foot at the ready...>
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? I'm not sure I can get behind that. If

However, it is correct. On some machines, physical address 0 is a valid
memory location (IIRC, the old CSC machines used lower addresses
(including 0) to access the registers). However, the compiler is
required to map a *constant* 0 value to the NULL pointer. (Even if the
mapping stores a completely different bit pattern into the pointer
variable.
nothing else, the compiler (or linker or loader, whatever) should disallow
storing at memory location 0.

The compiler will handle mapping the "address" you store into a pointer
into actual physical memory addresses. There is no requirement that the
value you "see" in your source code is the actual physical memory
address used by the operating system. Think of old DOS segmented memory
addresses where there were several (in-code) representations for a
single physical memory address.
Also, you are saying that 0 can live anywhere in memory and ptr = 0 (as in
char *ptr = 0) would be NULL. This part I get, and agree with.
<disengaging overheated gears, cooling with beer>

Cheers,
Ron
 
K

Keith Thompson

Mabden said:
<engaging brain, opening mouth, foot at the ready...>
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?

Yes (but please use the phrase "null pointer", not "NULL pointer";
NULL is a macro). I'm assuming that your 0000:0000 notation refers to
an all-bits-zero representation.
I'm not sure I can get behind that. If nothing else, the compiler
(or linker or loader, whatever) should disallow storing at memory
location 0.

Why should it?

Despite what K&R2 says on page 102, C says nothing special about an
all-bits-zero address. The only special address defined by the
language is the null pointer, which may or may not be represented as
all-bits-zero. (The wording in K&R2, as far as I can tell, is
consistent with a requirement that null pointers always being
represented as all-bits-zero. The standard itself is not, though of
course a given implementation is allowed to represent null pointers as
all-bits-zero if it chooses).
Also, you are saying that 0 can live anywhere in memory and ptr = 0 (as in
char *ptr = 0) would be NULL. This part I get, and agree with.
<disengaging overheated gears, cooling with beer>

0 is a null pointer constant, as is any integer constant expression
with the value 0, or such an expression cast to void*. Converting a
null pointer constant to any pointer type yields a null pointer, which
is guaranteed to compare unequal to a pointer to any object or
function.

In my opinion, the standard isn't quite as clear as it should be about
things that occur in source vs. things that exist at run time. A
"null pointer constant" is a construct that appears only in C source,
and is interpreted by the compiler. NULL is a macro that expands to a
null pointer constant; again, it appears only in C source. A "null
pointer" is a particular pointer value that can exist when a program
is running (and the source may no longer even exist).

Here's something that might clarify things a bit (or not).

Suppose you're designing a programming language. You need a distinct
pointer value that doesn't point to any object, to be used for things
like indicating that a memory allocation failed, marking the end of a
linked list, etc. Call this value a "nil pointer". You don't want
programmers to care how a "nil pointer" is represented (it might be
0xdeadbeef on one platform, 0xffffffff on another), so you have a
keyword "nil" to represent a nil pointer value:

//
// This is not C.
//
char *ptr = malloc(42);
if (ptr == nil) printf("malloc failed\n");

You can think of the keyword "nil" as a "nil pointer constant".

Now you have a nice clean language. Pointers and integers are two
entirely separate things, and there's no reason anyone should confuse
"nil" (a pointer value) with "zero" (an integer value).

Now you get some feedback from your customers. They complain that
"nil" takes too long to type; they want to use a literal 0 to indicate
a nil pointer value. You give in to their demands. But is "0"
equivalent to "1-1" or "0x0"? It turns out that the cleanest way to
make this work is to say that any integer constant expression with the
value 0, or such an expression cast to void*, is a "nil pointer
constant" (in addition to the existing "nil" keyword).

You release the new language specification, but there are still
complaints. Users don't want "nil" to be a keyword, since they want
to use it as an identifier. So in the next revision of your language,
you remove the "nil" keyword; a "nil pointer constant" is *just* an
integer constant expression with the value 0, or such an expression
cast to void*. You grumble that the users' complaints have messed up
your nice clean design; there'll probably need to be an entire section
in the FAQ just to explain this. And while you're at it, you change
the terminology a bit: "nil pointer" becomes "null pointer", and "nil
pointer constant" becomes "null pointer constant". And you add a NULL
macro that expands to a null pointer constant.

And now your new language is C.

(Incidentally, this is not how C actually evolved. There never was a
"nil" keyword; I'm fairly sure the use of 0 as a null pointer constant
goes back to the beginning, if not farther.)
 
O

Old Wolf

Malcolm said:
This code is undefined

char *ptr = 0;

*ptr = 1;

What has that got to do with the location zero?

When you assign '0' to a pointer in C, you get a null pointer,
not a pointer to the location zero. (Of course, on some architectures
those two things are the same, but many architectures are different).
 
M

Mabden

Keith Thompson said:
Mabden said:
<engaging brain, opening mouth, foot at the ready...>
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?

Yes (but please use the phrase "null pointer", not "NULL pointer";
NULL is a macro). I'm assuming that your 0000:0000 notation refers to
an all-bits-zero representation.

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.

NULL is a macro, I agree, for basically (char *)0. This would be a zero
somewhere in memory that the program stores upon startup and compares
various pointers to, so if NULL happens to point to 1234:4321, and I set
"ptr1 = ptr2 = NULL" then both pointers would point to 1234:4321. Any
allocation or function that returns NULL would be passing the address
1234:4321, and the program would consider that to mean the allocation
failed, or the pointer has not been initialized.

I think these things are distinct cases. 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. When I state that belief, I
sometimes get told I am wrong. I only have the K&R to go on. I do not own
any reference to the "Standard this that or the other". But, didn't the K&R
come first? To make a religious reference, there was a Bible, then a New
Testament, then the Book of Mormon. I feel like I am looking at the Bible,
and getting quotes from the Book of Mormon telling me I'm wrong. "We have a
new way of doing it now!" "You aren't up to the new standard..." But I sit
back and look at MY gospel, and say, "Know, you are wrong! And your standard
is wrong if you are telling me the truth about what it says."

If the new standard says that location 0:0 is available for data storage,
then it is your standard that is wrong. Any insults to my character
nonwithstanding, that is "the way it was" and I think should be "the way it
is". It matters not at all how many people in a room decided differently.
0:0 is the true null pointer - nothing may be stored or removed from 0:0.
Why should it?

Because it is the law. Why can't you travel at the speed of light?
Despite what K&R2 says on page 102, C says nothing special about an
all-bits-zero address. The only special address defined by the
language is the null pointer, which may or may not be represented as
all-bits-zero. (The wording in K&R2, as far as I can tell, is
consistent with a requirement that null pointers always being
represented as all-bits-zero. The standard itself is not, though of
course a given implementation is allowed to represent null pointers as
all-bits-zero if it chooses).

See above.
In my opinion, the standard isn't quite as clear as it should be about
things that occur in source vs. things that exist at run time. A
"null pointer constant" is a construct that appears only in C source,
and is interpreted by the compiler. NULL is a macro that expands to a
null pointer constant; again, it appears only in C source. A "null
pointer" is a particular pointer value that can exist when a program
is running (and the source may no longer even exist).

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 NULL macro may
be implementation dependant, but C _guarantees_ that if you point a pointer
at location 0:0, you are pointing at an invalid location, and no reading or
writing is allowed. It is the "Ultimate Null". Praise Zero!

Here's something that might clarify things a bit (or not).
Not.
 
J

junky_fellow

Historically, and in almost all C implementations, null pointers are
just pointers corresponding to the address 0. In these
implementations, if you put the integer zero into a location whose
size is the same as a pointer, and then treat that location as a
pointer, you will be doing exactly the same thing as if you had a real
null pointer.

The C standards don't require things to work like that though. They
make null pointers more abstract, like nil in Lisp or null in Java.
Null pointers *could* be represented so that they corresponded to the
address 0x12345678. In that case, the implementation would have to be
careful never to put a real object at address 0x12345678, and an
assignment like "int *foo = 0" or "int *foo = NULL" would have to be
compile to code that put the value 0x12345678 into foo's location.
Setting the location to zero by some means such as memset or calloc
would not work.

All this is quite separate from whether dereferencing a null pointer
causes some kind of exception. On modern machines with virtual memory
it's usual to unmap that page containing the null pointer address
(which in practice is page 0 - an implementation that represented null
pointers as 0x12345678 could unmap that page instead). This wasn't
always the case: a lot of early Vax C code assumed that null pointers
pointed to a byte containing zero, so that null pointers and empty
strings were interchangable. This practice was eradicated once people
ported their programs to machines like the early Suns, which did unmap
page 0.

-- Richard

If on some implementation address 0x12345678 represent a null pointer,
and address 0x0 is a valid address,
then if in my code i deliberately trying to compare some address
with 0x0 ( a valid address ), isn't this wrong on compiler side to
replace this 0x0 with its internal representation on null pointer?
(although i was trying to compare with some valid location)
Or i should never use hard coded address values except NULL
for pointer comparisons ?
 
C

Christian Bau

If on some implementation address 0x12345678 represent a null pointer,
and address 0x0 is a valid address,
then if in my code i deliberately trying to compare some address
with 0x0 ( a valid address ), isn't this wrong on compiler side to
replace this 0x0 with its internal representation on null pointer?
(although i was trying to compare with some valid location)
Or i should never use hard coded address values except NULL
for pointer comparisons ?

How do you do that comparison?

Let's say you write

char* p = malloc (100);

and the call succeeds. "p == NULL" and "p == 0" will both be false.
However, it can be true that all the bits in p are zero on this
implementation.

If you write

int i = 0;
char* q = (char *) i;

then the C99 Standard guarantees that q is a null pointer. On this
implementation it means q will point to address 0x12345678 and it will
not be equal to p. Unlike most current compilers, a compiler for this
implementation will have to produce real code to cast from int to char*.


If int and char* have the same size and alignment, then you could try to
write

* (int *) &q = 0;

to set q to a null pointer. This will work on many implementations but
not on this one; it is indeed undefined behavior.
 
K

Keith Thompson

Mabden said:
Keith Thompson said:
Mabden said:
<engaging brain, opening mouth, foot at the ready...>
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?

Yes (but please use the phrase "null pointer", not "NULL pointer";
NULL is a macro). I'm assuming that your 0000:0000 notation refers to
an all-bits-zero representation.

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.

C uses the term "null pointer" with a very specific meaning. It is,
among other things, the value returned by a failing malloc() and the
value of of argv[argc]. It is not, I repeat not, necessarily
represented as all-bits-zero (though it can be and often is).

In the context of the C programming language, using the term "null" to
refer to an all-bits-zero address is only going to cause confusion.
NULL is a macro, I agree, for basically (char *)0.

Not quite. NULL expands to an an implementation-defined null pointer
constant (C99 7.17p3). A null pointer constant is an integer constant
expression with the value 0, or such an expression cast to type void*
(C99 6.3.2.2p3). (NULL was probably defined as (char*)0 on some
pre-ANSI implementations, but that's invalid in current C.)
This would be a zero somewhere in memory that the program stores
upon startup and compares various pointers to, so if NULL happens to
point to 1234:4321, and I set "ptr1 = ptr2 = NULL" then both
pointers would point to 1234:4321. Any allocation or function that
returns NULL would be passing the address 1234:4321, and the program
would consider that to mean the allocation failed, or the pointer
has not been initialized.

I'd say that the phrase "a zero somewhere in memory" is a bit
misleading, and there's nothing that's necessarily stored upon
startup, but that's basically correct.
I think these things are distinct cases. 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. When I state
that belief, I sometimes get told I am wrong. I only have the K&R to
go on. I do not own any reference to the "Standard this that or the
other". But, didn't the K&R come first? To make a religious
reference, there was a Bible, then a New Testament, then the Book of
Mormon. I feel like I am looking at the Bible, and getting quotes
from the Book of Mormon telling me I'm wrong. "We have a new way of
doing it now!" "You aren't up to the new standard..." But I sit back
and look at MY gospel, and say, "Know, you are wrong! And your
standard is wrong if you are telling me the truth about what it
says."

Sorry, but the language really is defined by the ISO standard.
(There's some dispute about whether the C90 or C99 standard is
currently more important, but they're consistent with each other in
this particular area.) If K&R2 conflicts with the standard, K&R2 is
in error. This isn't a religious issue; Kernighan and Ritchie
themselves would tell you the same thing. Take a look at the errata
list at <http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html>.

My copy of K&R2 isn't handy at the moment, but I was looking at it
earlier today. The text on page 102 is a tutorial, not a reference.
There is a language reference in Appendix A. Look up "null pointer
constant" in the index. Read the section of Appendix A that discusses
null pointer constants. It does not say anything about an
all-bits-zero address.
If the new standard says that location 0:0 is available for data storage,
then it is your standard that is wrong. Any insults to my character
nonwithstanding, that is "the way it was" and I think should be "the way it
is". It matters not at all how many people in a room decided differently.
0:0 is the true null pointer - nothing may be stored or removed from 0:0.

I don't recall insulting your character; if I did, it was unintentional.

An implementation in which the all-bits-zero address is available for
data storage can be (and in which a null pointer is represented as,
say, all-bits-one) can be perfectly conforming.
Because it is the law. Why can't you travel at the speed of light?

There is no such law.

[...]
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 NULL macro may be implementation dependant, but C
_guarantees_ that if you point a pointer at location 0:0, you are
pointing at an invalid location, and no reading or writing is
allowed. It is the "Ultimate Null". Praise Zero!

No, it isn't. The only basis for this is a single ambiguous statement
in K&R2. Appendix A of K&R2 and the ISO standard (both C90 and C99)
are perfectly clear on this point; there is nothing special about an
all-bits-zero pointer.

Ok, try section 5 of the C FAQ.
 
K

kal

It's not K&R's finest moment. Here's a bit more context:

If not, alloc must return some signal that no space is left. C
guarantees that zero is never a valid address for data, so a return
value of zero can be used to signal an abnormal event, in this case,
no space.

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.

Here are some passages from C99.

6.3.2.3 Pointers

3 An integer constant expression with the value 0, or such an
expression cast to type void *, is called a null pointer
constant. If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer,
is guaranteed to compare unequal to a pointer to any object
or function.

4 Conversion of a null pointer to another pointer type yields
a null pointer of that type. Any two null pointers shall
compare equal.

5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity
of the referenced type, and might be a trap representation.

6 Any pointer type may be converted to an integer type. Except
as previously specified, the result is implementation-defined.
If the result cannot be represented in the integer type, the
behavior is undefined. The result need not be in the range of
values of any integer type.
 
R

Richard Bos

If you write

int i = 0;
char* q = (char *) i;

then the C99 Standard guarantees that q is a null pointer.

Oh? C&V, please. AFAICT it guarantees nothing of the sort; in fact, it
suggests (albeit in a footnote) that q _should_ have the value
0x00000000 if possible, and on junky_fellow's hypothetical platform that
would definitely not be a null pointer.

OTOH, if you did this

char *q=0;

or even, more superfluously,

char *q=(char *)0;

then q would be a null pointer, since 0 is a null pointer constant, and
both assignment to and casting to a pointer object are pointer contexts.

Richard
 
R

Richard Bos

Mabden said:
Keith Thompson said:
Mabden 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.
NULL is a macro, I agree, for basically (char *)0.

No, it isn't.
This would be a zero somewhere in memory

No, it isn't.
that the program stores upon startup and compares
various pointers to, so if NULL happens to point to 1234:4321, and I set
"ptr1 = ptr2 = NULL" then both pointers would point to 1234:4321.

Almost. But not quite.
I think these things are distinct cases. My point was that null, ie: 0:0,

From this point on, your point is invalid, since null _need not_ be 0:0.
is considered an invalid location for data. Furthermore, I believe it is
"guaranteed" to be invalid for data in C.

Your beliefs are immaterial; only the Standard counts.
When I state that belief, I sometimes get told I am wrong. I only have the K&R to go on. I do not own
any reference to the "Standard this that or the other". But, didn't the K&R
come first?

So bloody what? Anglo-Saxon came before English, but when you check your
spelling, do you use the OED, or the DOE?
To make a religious reference,

Please don't. It only makes you sound like a prat.
"We have a new way of doing it now!" "You aren't up to the new standard..."
But I sit back and look at MY gospel, and say, "Know, you are wrong! And
your standard is wrong if you are telling me the truth about what it says."

Then, to put it bluntly, you are an idiot, and you'll never program in
C. In the light of this, all the rest of your post is unimportant.

Basically, you cannot be taught; you cannot be reasoned with; you are
not worth our attention. Welcome to the killfile.

Richard
 
K

Keith Thompson

Christian Bau said:
If you write

int i = 0;
char* q = (char *) i;

then the C99 Standard guarantees that q is a null pointer. On this
implementation it means q will point to address 0x12345678 and it will
not be equal to p. Unlike most current compilers, a compiler for this
implementation will have to produce real code to cast from int to char*.

Um, no. The standard guarantees that a null pointer constant,
converted to a pointer type, results in a null pointer, but i is not a
null pointer constant. The value of q will be the
implementation-defined result of converting the int value 0 to char*;
this is typically all-bits-zero even if a null pointer is 0x12345678.
 
K

Keith Thompson

If on some implementation address 0x12345678 represent a null pointer,
and address 0x0 is a valid address,
then if in my code i deliberately trying to compare some address
with 0x0 ( a valid address ), isn't this wrong on compiler side to
replace this 0x0 with its internal representation on null pointer?

No, it's required.

The confusion is caused by the fact that we're using "0x0" in two
different senses. When you say that 0x0 is a valid address, you mean
(I presume) that an address whose representation is all-bits-zero is
valid -- but if 0x0 appears in a pointer context in C program source,
it refers to a null pointer, however that's represented. (That's why
I've been carefully using the phrase "all-bits-zero" in this thread.)
(although i was trying to compare with some valid location)
Or i should never use hard coded address values except NULL
for pointer comparisons ?

You can use NULL or a literal 0 to refer to a null pointer; they're
equivalent. If you want to use some other numeric value for a
pointer, you're in system-specific territory, and you'd better know
what you're doing.

Read section 5 of the C FAQ if you haven't already.
 
C

Christian Bau

Oh? C&V, please. AFAICT it guarantees nothing of the sort; in fact, it
suggests (albeit in a footnote) that q _should_ have the value
0x00000000 if possible, and on junky_fellow's hypothetical platform that
would definitely not be a null pointer.

1. Converting a null pointer constant to a pointer type yields a null
pointer. (BTW in an assignment char* q = 0; there is an actual
conversion from int to char*; this rule guarantees that the result is a
null pointer).

2. The result of conversion from integer to pointer type is
implementation defined, in other words, the result is defined.

3. The result of converting an integer value of zero is defined because
of (2), so far we know nothing about the result, but it will always be
the same because it is defined. In the special case that the integer
value of zero happens to be a constant integer expression, (1)
guarantees that the result is a null pointer. Since the result is always
the same, and sometimes a null pointer, it is always a null pointer.
 
C

Christian Bau

Keith Thompson said:
Um, no. The standard guarantees that a null pointer constant,
converted to a pointer type, results in a null pointer, but i is not a
null pointer constant. The value of q will be the
implementation-defined result of converting the int value 0 to char*;
this is typically all-bits-zero even if a null pointer is 0x12345678.

The implementation-defined result of the conversion must be a null
pointer if the int value 0 happens to be a null pointer constant. In
other words, the implementation is not free to define conversion from
int to char* in completely arbitrary ways.

In some cases, a value of zero must be converted to a null pointer. But
a conversion just converts values, it doesn't know about any syntactical
details how the value was derived; to the conversion a zero that happens
to be a null pointer constant and a zero that happens to be the value of
an int variable are the same. The result cannot be sometimes a null
pointer and sometimes not a null pointer. So in both cases the
conversion must give the same result, which must be a null pointer.
 
P

pete

The implementation-defined result of the conversion must be a null
pointer if the int value 0 happens to be a null pointer constant.

No.
The ordinary rules of conversion don't apply to
char *q = 0;
The assignment of a null pointer constant,
to a pointer object, is a special case.

int i = 0;
char* q = (char *)i;
is just implementation defined, and that's all that there is to it.
 
R

Richard Bos

Christian Bau said:
1. Converting a null pointer constant to a pointer type yields a null
pointer.

Irrelevant, since there are two conversions in that snippet: one in
which an integral constant zero is converted to an int value, and one in
which an int value is converted to a pointer value. Neither of these
involve a null pointer constant in a pointer context.
2. The result of conversion from integer to pointer type is
implementation defined, in other words, the result is defined.

Yes, but not necessarily a null pointer.
3. The result of converting an integer value of zero is defined because
of (2), so far we know nothing about the result, but it will always be
the same because it is defined.

Not necessarily. It may be defined as "the current user segment, with
the integer value as the offset" - with the current user segment
changing from program run to program run.
In the special case that the integer
value of zero happens to be a constant integer expression,

That makes about as much sense as "in the case that the person you're
talking to is a photograph of your brother". A constant integer
expression is a compile-time feature. An object with a value is a
run-time feature. The latter can never be the former.

Again: the exception is for compile-time, literal constant expressions
_alone_. Not for run-time values.

Richard
 
J

junky_fellow

Keith Thompson said:
No, it's required.

The confusion is caused by the fact that we're using "0x0" in two
different senses. When you say that 0x0 is a valid address, you mean
(I presume) that an address whose representation is all-bits-zero is
valid -- but if 0x0 appears in a pointer context in C program source,
it refers to a null pointer, however that's represented. (That's why
I've been carefully using the phrase "all-bits-zero" in this thread.)


You can use NULL or a literal 0 to refer to a null pointer; they're
equivalent. If you want to use some other numeric value for a
pointer, you're in system-specific territory, and you'd better know
what you're doing.

Read section 5 of the C FAQ if you haven't already.

thanx...
 

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