Looks like dereferencing a null pointer, but is ok???

Oskar Linde oskar.lindeREM at OVEgmail.com
Tue Sep 12 04:42:54 PDT 2006


Georg Wrede wrote:
> nobody wrote:
>>>>> void main()
>>>>> {
>>>>>     char[] foo = (cast(char*)null)[0..10];
>>>>> }
>>>
>>> I would have expected this to cause an error!
>>>
>>> And if really not, what in the world is
>>>
>>>    (cast(char*)null)[0..10]
>>>
>>> supposed to mean, or return???
>>
>> It is an array of the first 10 char elements starting from memory 
>> address 0.
> 
> In the ways not otherwise specified, D is alike C and C++, at least in 
> spirit.
> 
> Bjarne says (C++, 3rd ed. p 5.1.1) "No object is allocated with the 
> address 0. Consequently, 0 acts as a pointer literal, indicating that a 
> pointer doesn't refer to an object." ((I take it this means not only 
> class object instances but anything pointable at all.))
> 
> For some reason I got no compile time nor runtime error from this.

I don't see any reason you should. Merely handling null pointers is not 
an error.

> We're using the slice as an rvalue, so this constitutes a dereference of 
> a null pointer. And therefore an error.

It doesn't constitute a dereferencing as far as I can tell. You merely 
define a slice starting at the address null, being 10 chars long.

Should:

char *start = null;
int len = 10;

be illegal?

> (I seem to remember having read somewhere that modern systems don't give 
> user programs address spaces containing the zero address (even 
> virtually), precisely to avoid problems and pitfalls with null. Can 
> anybody confirm this?)
> 
> Further, since NULL is explicitly defined to not point to anything 
> (therefore not even the address zero), at best this code attempts to 
> return a slice out of thin air. In other words, garbage.

Yes. But it never touches the garbage.

> And specifically, even if there /was/ a zero address to point to, it 
> would still be illegal to return the slice.

Why? Should it be illegal to return an invalid pointer too?

> The following program does die (in windows) with an Access Violation:
> 
> import std.stdio;
> 
> void main()
> {
>         char[] foo = (cast(char*)null)[0..10];
> 
>     char c = foo[1];
> }
> 
> And we weren't even accessing foo[0]. :-)

AFAIK, most OS never map the virtual memory page 0 to anything, making 
accesses to this page illegal. With a page size of 4k, accessing 
anything within [0..4096] will give a guaranteed page fault.

> I consider it a bug when the compiler creates such an unusable array.
> I consider it an bug to not error on (cast(char*)null)[0..10].

I humbly disagree on both points.

/Oskar



More information about the Digitalmars-d-learn mailing list