Topic: std::copy on 3 nulls - degeneracy of nullptr/zero-pointer


Author: "peter miller" <fuchsia.groan@virgin.net>
Date: Mon, 21 Feb 2011 13:39:56 CST
Raw View
On Mon, 14 Feb 2011 10:32:51 -0000, Bjarke Hammersholt Roune
<bjarke.roune@gmail.com> wrote:

>
> MS VC++ 2010 is giving me assertion failures in debug mode when I run
> code like:
>
>  int* p = 0;
>  std::copy (p, p, p)
>
> It complains about there being a null pointer. I think that this is
> fine - it does not matter that the address can't be written to since
> the range is empty so I'm not asking for the range to be written to.

I think the problem here is the confusion between
(void*)0 and nullptr.  Consider, for a moment, a processor
where main memory is a simple array:

char main_memory[ 1 << ( CHAR_BIT * sizeof( void* ) ) ];

On this system pointers are isomorphic to the integers, so
for all

    size_t n;

where n < sizeof( main_memory ) it's true that

    &main_memory[ n ] == (void*)n;

Since main_memory[0] is a valid address, *(char*)0 should be
dereferenceable. (AFAIK this is true on the x86, provided
memory is mapped there; it certainly was in real mode.)

On such a machine it's entirely reasonable to code

std::copy( my_interrupt_vector_table.begin()
         , my_interrupt_vector_table.end()
         , (interrupt_vector*)0 );

or

std::copy( (interrupt_vector*)0, (interrupt_vector*)256
         , std::back_inserter( my_interrupt_vector_table ) );

So why not std::copy<char*,char*>( 0, 0, 0 )?

Back in the days of 8-bit micros, none of us blinked about 0
being the first usable address.

/Were/ std::copy<char*,char*>( 0, 0, 0) to be illegal, then
there'd be a fictitious black-hole in the address space:

char* p = (char*)( sizeof( main_memory ) - 1 );

std::copy( p, p, p ); // perfectly legal.
++p;                  // p wraps to zero,
std::copy( p, p, p ); // oops suddenly illegal
++p                   // p = (char*)1
std::copy( p, p, p );  // legal again! whohayyy!

Of course

std::copy<char*,char*>( nullptr, nullptr, nullptr );

*should* be illegal.

In general, the C++ concept of a "pointer to type T" is NOT
isomorphic to the integers, but to boost::optional<size_t>
The null pointer is the singular, undereferenceable
boost::optional<size_t>() whereas the zero pointer is the
perfectly dereferenceable boost::optional<size_t>( 0 ) and
should be a valid iterator.  Historically we've fudged the
issue, by allowing the integer 0 to represent both (4.10/1).
That degeneracy is the source of this problem.

Just my $0.02.

Peter

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


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





Author: "Martin B." <0xCDCDCDCD@gmx.at>
Date: Tue, 22 Feb 2011 10:57:59 CST
Raw View
On 21.02.2011 20:39, peter miller wrote:
>
> On Mon, 14 Feb 2011 10:32:51 -0000, Bjarke Hammersholt Roune
> <bjarke.roune@gmail.com> wrote:
>
>>
>> MS VC++ 2010 is giving me assertion failures in debug mode when I run
>> code like:
>>
>> int* p = 0;
>> std::copy (p, p, p)
>>
> .....
>
> Of course
>
> std::copy<char*,char*>( nullptr, nullptr, nullptr );
>
> *should* be illegal.
>
> In general, the C++ concept of a "pointer to type T" is NOT
> isomorphic to the integers, but to boost::optional<size_t>
> The null pointer is the singular, undereferenceable
> boost::optional<size_t>() whereas the zero pointer is the
> perfectly dereferenceable boost::optional<size_t>( 0 ) and
> should be a valid iterator.

But note that the (vague) way the standard uses the term 'singular',
it does appear that a nullptr is *not* singular as it seems implied
that you cannot even compare a singular value to another and you can
do so with a nullptr.

cheers,
Martin


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