Looks like dereferencing a null pointer, but is ok???
Georg Wrede
georg.wrede at nospam.org
Tue Sep 12 16:26:56 PDT 2006
Oskar Linde wrote:
> 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.
I humbly agree with you, on second thought. :-)
And with Sean and Regan in the other posts.
I admit I forgot that the slice is nothing more than a real estate
property claim, and not the thing itself. (But it did look scary at
first sight!)
I seldom need slices... which reminds me:
import std.stdio;
import std.gc;
void main()
{
int[] ia = new int[100];
int[] ib = ia[2..4];
ib[0] = 666;
ib[1] = 777;
delete ia;
std.gc.fullCollect();
char[] ca = new char[400];
writefln("ib[0]=%d and ib[1]=%d", ib[0], ib[1]);
}
which of course gives
ib[0]=-1 and ib[1]=-1
as totally expected -- by everyone else except the poor programmer,
whose code is larger than this example. :-)
Time for Dlint, at least for the programmer who forgot to adhere to the
Bovine rule.
More information about the Digitalmars-d-bugs
mailing list