Topic: Black-and-white simple clarification


Author: kuyper@wizard.net
Date: Mon, 21 Aug 2006 05:06:42 CST
Raw View
Greg Herlihy wrote:
> kuyper@wizard.net wrote:
> > Greg Herlihy wrote:
> > ..
> > > The defect has been corrected: "A valid value of an object pointer type
> > > represents either the address of a byte in memory (1.7) or a null
> > > pointer"    3.9.2/3. Since a pointer one past the end of an array is
> > > required to be an address in memory - it cannot ever be equal to a null
> > > pointer because a null pointer value does not represent an address in
> > > memory.
> >
> > Why can't a null pointer represent an address in memory?
> > I think mark may be right about the definition of null pointer values
> > being exhaustive, and if so, that covers the problem.
>
> For one, the "either... or..." contrast certainly suggests that a

Ordinary English usage does not support your interpretation of "either
.. or ..." as an exclusive or. Consider: "He is either a Redskins fan
or a hot dog lover." Does that sentence suggest to you that the person
referred to can't be both?

> our abstract machine). Furthermore, were a null pointer also to
> represent an address in memory - than a null pointer would no longer be
> distinguishable from an object residing - or one that could be residing
> - at that address.

That's quite normally the case. Many real world implementations use a
pointer representing a specific address, usually 0, as a null pointer.
So long as there's no object that is or could be accessible to a
strictly conforming program allocated at that address, that doesn't
cause a problem.

> > However, I can't find anything in the standard prohibiting a null
> > pointer value from representing a memory location. If it did, there'd
> > be a lot of non-conforming implementations out there. It is in fact
> > quite normal for implementations to implement null pointer values as
> > pointers that happens to represent an actual address in memory; usually
> > address 0. Code that demonstrates this fact has, inherently, behaviour
> > that is undefined by the standard; but on such platforms, the behavior
> > which actually happens when you dereference or perform pointer
> > arithmetic on a null pointer value is precisely the behavior of a
> > pointer that represents that location. On decent operating systems,
> > that's a memory access violation that quickly aborts your program; but
> > that's precisely because the memory location that it represents is off
> > limits.
>
> As noted above, memory that is "off-limits" to a program is not any
> kind of memory at all as far as the program is concerned. It
> effectively does not exist. So if none of a program's objects are ever
> allocated at address 0 - then the address 0 is not in memory. In that
> case, the implementation would be free to use address 0 as the
> implementation-defined value representing a null pointer.

The memory pointed at by a one-past-the-end pointer is also off limits.
Just like a null pointer, it cannot be dereferenced by code with
defined behavior. Therefore, that's not a barrier to having a null
pointer and a pointer one-past-the-end be pointers referring to the
same unused memory location.

> > And that is precisely the point: because null pointers often do
> > represent a memory location, it is quite possible for one-past-the-end
> > pointers to point to that same location, unless an implementation is
> > actually prohibited from placing an object in such a location that this
> > would be the case. 3.9.2p3 isn't what prohibits that. 4.10p1 might be.
>
> No, not only does a null pointer never represent an address in
> (program) memory - it cannot be taken for a non-null pointer that may
> point to an address in memory. Since a one-past-the-end of an array
> points to an object that is possibly residing at that address - it is
> inherently a non-null pointer. And footnote 80 in    5.7/6 reaches a
> similar conclusion:
>
> "[...] an implementation need only provide one extra byte (which might
> overlap another object in the program) just after the end of the object
> in order to satisfy the "one past the last element" requirements."

That permits a pointer one-past-the end to also be a pointer to an
object; but it doesn't require it to be one. If it did, every
implementation that fails to allocate an object after every
user-defined or user-accessible object would be non-conforming, and I
suspect that description would cover almost every implementation that
has ever existed.

The one extra byte need not be part of an actual object; it could, in
particular, be the same unused byte that on some systems is referred to
by null pointers.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "kanze" <kanze@gabi-soft.fr>
Date: Mon, 21 Aug 2006 05:02:28 CST
Raw View
Greg Herlihy wrote:
> kuyper@wizard.net wrote:
> > mark wrote:
> > > kuyper@wizard.net wrote:
> > > > mark wrote:

> The defect has been corrected: "A valid value of an object
> pointer type represents either the address of a byte in memory
> (1.7) or a null pointer"    3.9.2/3. Since a pointer one past
> the end of an array is required to be an address in memory -
> it cannot ever be equal to a null pointer because a null
> pointer value does not represent an address in memory.

I don't see where a pointer one past the end of an array is
required to be an address in accessible memory.  All that is
required is that the system be able to load and store it.  And
of course, a null pointer can also be an address in memory; it
just cannot be the address of a C++ object or function.  (In the
past, it was even usual that the null pointer was an address in
memory.  In fact, in many cases, it couldn't not be, because
there was no possible pointer value which wasn't an address in
memory.  On an 8080, you're not going to make pointers three
bytes, just because you have 64 KB.)

> As a footnote points out, supporting
> one-past-the-end-of-an-array pointers requires that at least
> one addressable byte exist at the end of every array (although
> that extra byte can be part of a different object).

I'm not sure which footnote you're refering to.  But I know that
there was some discussion about this a long time ago, the issue
being how do you implement C on a machine where loading a
pointer to an invalid address causes a hardware trap.  The
answer was that on such a machine, you had to map at least one
extra byte for an object at the end of the mapped memory.

> In fact that last point does mean that a
> one-past-the-end-of-an-array pointer could be equal to a
> pointer to another object or to another array. So a program
> should be prepared for that exigency. But there is no reason
> for a program to expect such a pointer ever to be equal to the
> null pointer constant - because it won't be.

In practice, I think you're right, and I think that the
standard(s---C is concerned as well) should be corrected to
guarantee this.  But the current situation is far from clear.

--
James Kanze                                           GABI Software
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: wkaras@yahoo.com
Date: Tue, 22 Aug 2006 10:52:08 CST
Raw View
Frederick Gotham wrote:
> May I propose that, in the next Standard, explicit clarification be given
> regarding whether a pointer to "one past the last element of an array" can
> be identical to a null pointer.
>
> Sample Code:
>
> #include <cassert>
>
> int main()
> {
>     int array[4];
>
>     int const *const p = array + 4;
>
>     assert(p);
> }
>
> There has been quite a bit of debate on this... and each thread that
> discusses it seems to go deep into a spiralling black hole.
>
> Therefore, I propose that the next Standard make the simple black-and-white
> clarification. Either:
>
>     (1) A pointer to "one past the last element of an array" can be a null
> pointer.
>
> or:
>
>     (2) A pointer to "one past the last element of an array" shall be
> distinct from a null pointer.
.

Doesn't the Standard guarantee that for an array a of dimension N,
a + i < a + j if i < j <= N ?  For every CPU architecture that I know
of, this effectively forces that arrays are not located at the "end"
of memory, so that a + N is not null, and thus null is not a special
case in every pointer compare.  But suppose hypothetically there
were a CPU with a "pucmp" compare instruction that subtracted
one from each operand before comparing them (unsigned).  If this
were used to compare pointers, then you could have an array
at the end of memory with a + N == 0, and the above guarantee
would hold.  But in what situation would that be a problem?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Fri, 18 Aug 2006 10:01:52 CST
Raw View
kuyper@wizard.net wrote:
> Greg Herlihy wrote:
> ..
> > The defect has been corrected: "A valid value of an object pointer type
> > represents either the address of a byte in memory (1.7) or a null
> > pointer"    3.9.2/3. Since a pointer one past the end of an array is
> > required to be an address in memory - it cannot ever be equal to a null
> > pointer because a null pointer value does not represent an address in
> > memory.
>
> Why can't a null pointer represent an address in memory?
> I think mark may be right about the definition of null pointer values
> being exhaustive, and if so, that covers the problem.

For one, the "either... or..." contrast certainly suggests that a
pointer cannot be null and refer to an an address in memory at the same
time. (Note also the term "memory" here of course can refer only to
program memory - since that is the only type of memory contemplated in
our abstract machine). Furthermore, were a null pointer also to
represent an address in memory - than a null pointer would no longer be
distinguishable from an object residing - or one that could be residing
- at that address.

> However, I can't find anything in the standard prohibiting a null
> pointer value from representing a memory location. If it did, there'd
> be a lot of non-conforming implementations out there. It is in fact
> quite normal for implementations to implement null pointer values as
> pointers that happens to represent an actual address in memory; usually
> address 0. Code that demonstrates this fact has, inherently, behaviour
> that is undefined by the standard; but on such platforms, the behavior
> which actually happens when you dereference or perform pointer
> arithmetic on a null pointer value is precisely the behavior of a
> pointer that represents that location. On decent operating systems,
> that's a memory access violation that quickly aborts your program; but
> that's precisely because the memory location that it represents is off
> limits.

As noted above, memory that is "off-limits" to a program is not any
kind of memory at all as far as the program is concerned. It
effectively does not exist. So if none of a program's objects are ever
allocated at address 0 - then the address 0 is not in memory. In that
case, the implementation would be free to use address 0 as the
implementation-defined value representing a null pointer.

> And that is precisely the point: because null pointers often do
> represent a memory location, it is quite possible for one-past-the-end
> pointers to point to that same location, unless an implementation is
> actually prohibited from placing an object in such a location that this
> would be the case. 3.9.2p3 isn't what prohibits that. 4.10p1 might be.

No, not only does a null pointer never represent an address in
(program) memory - it cannot be taken for a non-null pointer that may
point to an address in memory. Since a one-past-the-end of an array
points to an object that is possibly residing at that address - it is
inherently a non-null pointer. And footnote 80 in    5.7/6 reaches a
similar conclusion:

"[...] an implementation need only provide one extra byte (which might
overlap another object in the program) just after the end of the object
in order to satisfy the "one past the last element" requirements."

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Harald van =?UTF-8?B?RMSzaw==?= <truedfx@gmail.com>
Date: Fri, 18 Aug 2006 11:49:29 CST
Raw View
Greg Herlihy wrote:
> kuyper@wizard.net wrote:
>> mark wrote:
>> > kuyper@wizard.net wrote:
>> > > mark wrote:
>> > > > A /null pointer constant/ is an integral constant expression rvalue
>> > > > of integer type that evaluates to zero. A null pointer constant can
>> > > > be converted to a pointer type; the result is the /null pointer
>> > > > value/ of that type and is distinuishable from every other value of
>> > > > pointer to object or pointer to function type.
>> .
>> > > That doesn't quite work, because I don't think there's anything that
>> > > says that a pointer one past the end has to have a value "other" than
>> > > null. If if has the same null value as the value of a null pointer
>> > > constant, then it's not only permitted, but required, to compare
>> > > equal.
>> >
>> > Except that that paragraph *defines* a null pointer value. Doesnt that
>> > make it exhaustive? (and yes, I know that some library functions can
>> > return a null pointer value - I dont believe that changes the
>> > argument).
>>
>> You might be right there.
>>
>> > > The problem with this logic is that it applies equally well to any
>> > > pointer value, including ones that point at actual objects.
>> >
>> > So even if Im wrong above, and the definition is not exhaustive, then
>> > there are two ways to interpret the paragraph. One makes sense, and the
>> > other doesnt...
>>
>> When there are two ways to interpret a paragraph in the standard, and
>> one makes sense and the other doesn't, the only conclusion we're
>> justified in making is that the standard is defective. We're not
>> entitled to conclude that, when the defect is fixed, the corrected text
>> will still be consistent with the only interpretation of the defective
>> text that makes sense.
>
> The defect has been corrected: "A valid value of an object pointer type
> represents either the address of a byte in memory (1.7) or a null
> pointer"   3.9.2/3. Since a pointer one past the end of an array is
> required to be an address in memory -

What requires this?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: fgothamNO@SPAM.com (Frederick Gotham)
Date: Tue, 8 Aug 2006 12:04:10 GMT
Raw View
May I propose that, in the next Standard, explicit clarification be given
regarding whether a pointer to "one past the last element of an array" can
be identical to a null pointer.

Sample Code:

#include <cassert>

int main()
{
    int array[4];

    int const *const p = array + 4;

    assert(p);
}

There has been quite a bit of debate on this... and each thread that
discusses it seems to go deep into a spiralling black hole.

Therefore, I propose that the next Standard make the simple black-and-white
clarification. Either:

    (1) A pointer to "one past the last element of an array" can be a null
pointer.

or:

    (2) A pointer to "one past the last element of an array" shall be
distinct from a null pointer.

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Wed, 9 Aug 2006 09:29:21 CST
Raw View
Frederick Gotham wrote:
> May I propose that, in the next Standard, explicit clarification be given
> regarding whether a pointer to "one past the last element of an array" can
> be identical to a null pointer.
>
> Sample Code:
>
> #include <cassert>
>
> int main()
> {
>     int array[4];
>
>     int const *const p = array + 4;
>
>     assert(p);
> }
>
> There has been quite a bit of debate on this... and each thread that
> discusses it seems to go deep into a spiralling black hole.
>
> Therefore, I propose that the next Standard make the simple black-and-white
> clarification. Either:
>
>     (1) A pointer to "one past the last element of an array" can be a null
> pointer.
>
> or:
>
>     (2) A pointer to "one past the last element of an array" shall be
> distinct from a null pointer.

I suspect it'll be "clarified" to be implementation defined. Point (2)
specifically means that for systems where if you add one to the highest
possible (valid?) memory address, you get zero, the runtime system has
to ensure that no valid pointers to the topmost memory address can
exist. I wouldn't much like to totally ensure that for any system.
However, on some systems it is easy to guarantee (2).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "mark" <markw65@gmail.com>
Date: Wed, 9 Aug 2006 10:34:42 CST
Raw View
ThosRTanner wrote:
> Frederick Gotham wrote:
> > May I propose that, in the next Standard, explicit clarification be given
> > regarding whether a pointer to "one past the last element of an array" can
> > be identical to a null pointer.
> >
> > Sample Code:
> >
> > #include <cassert>
> >
> > int main()
> > {
> >     int array[4];
> >
> >     int const *const p = array + 4;
> >
> >     assert(p);
> > }
> >
> > There has been quite a bit of debate on this... and each thread that
> > discusses it seems to go deep into a spiralling black hole.
> >
> > Therefore, I propose that the next Standard make the simple black-and-white
> > clarification. Either:
> >
> >     (1) A pointer to "one past the last element of an array" can be a null
> > pointer.
> >
> > or:
> >
> >     (2) A pointer to "one past the last element of an array" shall be
> > distinct from a null pointer.
>
> I suspect it'll be "clarified" to be implementation defined. Point (2)
> specifically means that for systems where if you add one to the highest
> possible (valid?) memory address, you get zero, the runtime system has
> to ensure that no valid pointers to the topmost memory address can
> exist. I wouldn't much like to totally ensure that for any system.
> However, on some systems it is easy to guarantee (2).

I know this subject was discussed recently, and that the concensus was
that the standard didnt prohibit this, but 4.10/1 appears to me to do
so. Perhaps Im missing something:

A /null pointer constant/ is an integral constant expression rvalue of
integer type that evaluates to zero. A null pointer constant can be
converted to a pointer type; the result is the /null pointer value/ of
that type and is distinuishable from every other value of pointer to
object or pointer to function type.

Note that it doesnt say "from every other pointer to object"; it says
"from every other value of pointer to object type". Unless Im missing
something, a pointer one-past-the end *is* a value of pointer to object
type (even though its not a pointer to an object), and so is
distinguishable from the null pointer value.

Mark Williams

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: eugalt@verizon.net ("Eugene Alterman")
Date: Wed, 9 Aug 2006 18:10:21 GMT
Raw View
"mark" <markw65@gmail.com> wrote in message
news:1155136598.724437.235780@i3g2000cwc.googlegroups.com...
>
> ThosRTanner wrote:
>> Frederick Gotham wrote:
>> > May I propose that, in the next Standard, explicit clarification be
>> > given
>> > regarding whether a pointer to "one past the last element of an array"
>> > can
>> > be identical to a null pointer.
>> >
>> > Sample Code:
>> >
>> > #include <cassert>
>> >
>> > int main()
>> > {
>> >     int array[4];
>> >
>> >     int const *const p = array + 4;
>> >
>> >     assert(p);
>> > }
>> >
>> > There has been quite a bit of debate on this... and each thread that
>> > discusses it seems to go deep into a spiralling black hole.
>> >
>> > Therefore, I propose that the next Standard make the simple
>> > black-and-white
>> > clarification. Either:
>> >
>> >     (1) A pointer to "one past the last element of an array" can be a
>> > null
>> > pointer.
>> >
>> > or:
>> >
>> >     (2) A pointer to "one past the last element of an array" shall be
>> > distinct from a null pointer.
>>
>> I suspect it'll be "clarified" to be implementation defined. Point (2)
>> specifically means that for systems where if you add one to the highest
>> possible (valid?) memory address, you get zero, the runtime system has
>> to ensure that no valid pointers to the topmost memory address can
>> exist. I wouldn't much like to totally ensure that for any system.
>> However, on some systems it is easy to guarantee (2).
>
> I know this subject was discussed recently, and that the concensus was
> that the standard didnt prohibit this, but 4.10/1 appears to me to do
> so. Perhaps Im missing something:
>
> A /null pointer constant/ is an integral constant expression rvalue of
> integer type that evaluates to zero. A null pointer constant can be
> converted to a pointer type; the result is the /null pointer value/ of
> that type and is distinuishable from every other value of pointer to
> object or pointer to function type.

But any value is distinguishable from any other value - that's the meaning
of the word "other".
Otherwise it woud be the same value, I guess.
Or does it mean every value that is not a copy of a null pointer constant
converted to the pointer type?

> Note that it doesnt say "from every other pointer to object"; it says
> "from every other value of pointer to object type". Unless Im missing
> something, a pointer one-past-the end *is* a value of pointer to object
> type (even though its not a pointer to an object), and so is
> distinguishable from the null pointer value.
>
> Mark Williams
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Thu, 10 Aug 2006 08:48:09 CST
Raw View
mark posted:

> I know this subject was discussed recently, and that the concensus was
> that the standard didnt prohibit this, but 4.10/1 appears to me to do
> so. Perhaps Im missing something:
>
> A /null pointer constant/ is an integral constant expression rvalue of
> integer type that evaluates to zero. A null pointer constant can be
> converted to a pointer type; the result is the /null pointer value/ of
> that type and is distinuishable from every other value of pointer to
> object or pointer to function type.


I wouldn't make any assumption based on that. It's ambiguous. It should be
explicit:

"the result is the /null pointer value/ of that type and is distinuishable
from every other value of pointer to object or pointer to function type
(including a pointer to "one past the last element of an array").

--

Frederick Gotham

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Thu, 10 Aug 2006 08:48:51 CST
Raw View
mark wrote:
> ThosRTanner wrote:
> > Frederick Gotham wrote:
.
> > > Therefore, I propose that the next Standard make the simple black-and-white
> > > clarification. Either:
> > >
> > >     (1) A pointer to "one past the last element of an array" can be a null
> > > pointer.
> > >
> > > or:
> > >
> > >     (2) A pointer to "one past the last element of an array" shall be
> > > distinct from a null pointer.
> >
> > I suspect it'll be "clarified" to be implementation defined. Point (2)
> > specifically means that for systems where if you add one to the highest
> > possible (valid?) memory address, you get zero, the runtime system has
> > to ensure that no valid pointers to the topmost memory address can
> > exist. I wouldn't much like to totally ensure that for any system.
> > However, on some systems it is easy to guarantee (2).
>
> I know this subject was discussed recently, and that the concensus was
> that the standard didnt prohibit this, but 4.10/1 appears to me to do
> so. Perhaps Im missing something:
>
> A /null pointer constant/ is an integral constant expression rvalue of
> integer type that evaluates to zero. A null pointer constant can be
> converted to a pointer type; the result is the /null pointer value/ of
> that type and is distinuishable from every other value of pointer to
> object or pointer to function type.

OK, so there is a difference between C and C++ on this issue. That's
bad (see below).

> Note that it doesnt say "from every other pointer to object"; it says
> "from every other value of pointer to object type". Unless Im missing
> something, a pointer one-past-the end *is* a value of pointer to object
> type (even though its not a pointer to an object), and so is
> distinguishable from the null pointer value.

That doesn't quite work, because I don't think there's anything that
says that a pointer one past the end has to have a value "other" than
null. If if has the same null value as the value of a null pointer
constant, then it's not only permitted, but required, to compare equal.

The problem with this logic is that it applies equally well to any
pointer value, including ones that point at actual objects. That's why
the C equivalent of this clause is superior, it prohibits a null
pointer from comparing equal to a pointer to any object, rather than a
pointer of any object type. A pointer to one past the end of an array
might not point at an object, and therefore could be null. However, a
pointer to the first element of an array certainly does point at an
object, and is therefore prohibited from comparing equal to a null
pointer.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "mark" <markw65@gmail.com>
Date: Fri, 11 Aug 2006 10:55:59 CST
Raw View
kuyper@wizard.net wrote:
> mark wrote:

> >
> > A /null pointer constant/ is an integral constant expression rvalue of
> > integer type that evaluates to zero. A null pointer constant can be
> > converted to a pointer type; the result is the /null pointer value/ of
> > that type and is distinuishable from every other value of pointer to
> > object or pointer to function type.
>
> OK, so there is a difference between C and C++ on this issue. That's
> bad (see below).
>
> > Note that it doesnt say "from every other pointer to object"; it says
> > "from every other value of pointer to object type". Unless Im missing
> > something, a pointer one-past-the end *is* a value of pointer to object
> > type (even though its not a pointer to an object), and so is
> > distinguishable from the null pointer value.
>
> That doesn't quite work, because I don't think there's anything that
> says that a pointer one past the end has to have a value "other" than
> null. If if has the same null value as the value of a null pointer
> constant, then it's not only permitted, but required, to compare equal.

Except that that paragraph *defines* a null pointer value. Doesnt that
make it exhaustive? (and yes, I know that some library functions can
return a null pointer value - I dont believe that changes the
argument).

>
> The problem with this logic is that it applies equally well to any
> pointer value, including ones that point at actual objects.

So even if Im wrong above, and the definition is not exhaustive, then
there are two ways to interpret the paragraph. One makes sense, and the
other doesnt...

Mark

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Fri, 11 Aug 2006 13:10:51 CST
Raw View
mark wrote:
> kuyper@wizard.net wrote:
> > mark wrote:
>
> > >
> > > A /null pointer constant/ is an integral constant expression rvalue of
> > > integer type that evaluates to zero. A null pointer constant can be
> > > converted to a pointer type; the result is the /null pointer value/ of
> > > that type and is distinuishable from every other value of pointer to
> > > object or pointer to function type.
.
> > That doesn't quite work, because I don't think there's anything that
> > says that a pointer one past the end has to have a value "other" than
> > null. If if has the same null value as the value of a null pointer
> > constant, then it's not only permitted, but required, to compare equal.
>
> Except that that paragraph *defines* a null pointer value. Doesnt that
> make it exhaustive? (and yes, I know that some library functions can
> return a null pointer value - I dont believe that changes the
> argument).

You might be right there.

> > The problem with this logic is that it applies equally well to any
> > pointer value, including ones that point at actual objects.
>
> So even if Im wrong above, and the definition is not exhaustive, then
> there are two ways to interpret the paragraph. One makes sense, and the
> other doesnt...

When there are two ways to interpret a paragraph in the standard, and
one makes sense and the other doesn't, the only conclusion we're
justified in making is that the standard is defective. We're not
entitled to conclude that, when the defect is fixed, the corrected text
will still be consistent with the only interpretation of the defective
text that makes sense.

I don't like the possibility that one-past-the end pointers are null;
so I hope your interpretation is correct. I think there's probably a
fair amount of code out there which checks end-of-range pointers for
null values, and behaves differently if they are, on the assumption
that they can't be a valid end-of-range pointer. That seems like a
reasonable assumption to me.
For typical architectures it means that no object that the user can
access can be allocated so as to include the byte that would be pointed
at by (char*)0 -1, if that code were legal. There might be
architectures where it would be a serious burden, but I haven't heard
anyone describe such an architecture.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Fri, 11 Aug 2006 17:58:08 CST
Raw View
kuyper@wizard.net wrote:
> mark wrote:
> > kuyper@wizard.net wrote:
> > > mark wrote:
> >
> > > >
> > > > A /null pointer constant/ is an integral constant expression rvalue of
> > > > integer type that evaluates to zero. A null pointer constant can be
> > > > converted to a pointer type; the result is the /null pointer value/ of
> > > > that type and is distinuishable from every other value of pointer to
> > > > object or pointer to function type.
> .
> > > That doesn't quite work, because I don't think there's anything that
> > > says that a pointer one past the end has to have a value "other" than
> > > null. If if has the same null value as the value of a null pointer
> > > constant, then it's not only permitted, but required, to compare equal.
> >
> > Except that that paragraph *defines* a null pointer value. Doesnt that
> > make it exhaustive? (and yes, I know that some library functions can
> > return a null pointer value - I dont believe that changes the
> > argument).
>
> You might be right there.
>
> > > The problem with this logic is that it applies equally well to any
> > > pointer value, including ones that point at actual objects.
> >
> > So even if Im wrong above, and the definition is not exhaustive, then
> > there are two ways to interpret the paragraph. One makes sense, and the
> > other doesnt...
>
> When there are two ways to interpret a paragraph in the standard, and
> one makes sense and the other doesn't, the only conclusion we're
> justified in making is that the standard is defective. We're not
> entitled to conclude that, when the defect is fixed, the corrected text
> will still be consistent with the only interpretation of the defective
> text that makes sense.

The defect has been corrected: "A valid value of an object pointer type
represents either the address of a byte in memory (1.7) or a null
pointer"    3.9.2/3. Since a pointer one past the end of an array is
required to be an address in memory - it cannot ever be equal to a null
pointer because a null pointer value does not represent an address in
memory.

As a footnote points out, supporting one-past-the-end-of-an-array
pointers requires that at least one addressable byte exist at the end
of every array (although that extra byte can be part of a different
object). In fact that last point does mean that a
one-past-the-end-of-an-array pointer could be equal to a pointer to
another object or to another array. So a program should be prepared for
that exigency. But there is no reason for a program to expect such a
pointer ever to be equal to the null pointer constant - because it
won't be.

Greg


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Tue, 15 Aug 2006 09:01:08 CST
Raw View
Greg Herlihy wrote:
..
> The defect has been corrected: "A valid value of an object pointer type
> represents either the address of a byte in memory (1.7) or a null
> pointer"    3.9.2/3. Since a pointer one past the end of an array is
> required to be an address in memory - it cannot ever be equal to a null
> pointer because a null pointer value does not represent an address in
> memory.

Why can't a null pointer represent an address in memory?
I think mark may be right about the definition of null pointer values
being exhaustive, and if so, that covers the problem.

However, I can't find anything in the standard prohibiting a null
pointer value from representing a memory location. If it did, there'd
be a lot of non-conforming implementations out there. It is in fact
quite normal for implementations to implement null pointer values as
pointers that happens to represent an actual address in memory; usually
address 0. Code that demonstrates this fact has, inherently, behaviour
that is undefined by the standard; but on such platforms, the behavior
which actually happens when you dereference or perform pointer
arithmetic on a null pointer value is precisely the behavior of a
pointer that represents that location. On decent operating systems,
that's a memory access violation that quickly aborts your program; but
that's precisely because the memory location that it represents is off
limits.

And that is precisely the point: because null pointers often do
represent a memory location, it is quite possible for one-past-the-end
pointers to point to that same location, unless an implementation is
actually prohibited from placing an object in such a location that this
would be the case. 3.9.2p3 isn't what prohibits that. 4.10p1 might be.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]