Jump to page: 1 2
Thread overview
Empty associative array crashes program
Apr 01, 2013
Luís Marques
Apr 01, 2013
Jonathan M Davis
Apr 01, 2013
Luís Marques
Apr 01, 2013
Luís Marques
Apr 02, 2013
bearophile
Apr 02, 2013
H. S. Teoh
Apr 02, 2013
Luís Marques
Apr 02, 2013
Maxim Fomin
Apr 02, 2013
Timothee Cour
Apr 02, 2013
Jonathan M Davis
Apr 02, 2013
Timothee Cour
April 01, 2013
I added a bug to the database, because the following code results in a segfault (DMD v2.062, OS X 10.8.3, 64-bit):

    #!/usr/local/bin/rdmd

    @safe:

    void main()
    {
        int[string] a;
        a["foo"] = 0;
        a.remove("foo");
        assert(a != null); // segfault (not exception)
    }

Now I come here for some further clarifications. While it seems fairly clear to me that the assert should not crash the program with a segmentation fault (at least with @safe), is the assert actually true? (Is it even specified by the language if the AA can become null again, after removing the last item?)

Second, I didn't test this in other OSes, but assuming the bug is reproducible, am I actually the first one to trip on this issue? It seems too basic, but I didn't find a duplicate in the bug database.

Best regards,
Luís
April 01, 2013
On Monday, April 01, 2013 22:32:01 =?UTF-8?B?Ikx1w61z?=.Marques <luismarques@gmail.com>@puremagic.com wrote:
> I added a bug to the database, because the following code results in a segfault (DMD v2.062, OS X 10.8.3, 64-bit):
> 
> #!/usr/local/bin/rdmd
> 
> @safe:
> 
> void main()
> {
> int[string] a;
> a["foo"] = 0;
> a.remove("foo");
> assert(a != null); // segfault (not exception)
> }
> 
> Now I come here for some further clarifications. While it seems fairly clear to me that the assert should not crash the program with a segmentation fault (at least with @safe), is the assert actually true? (Is it even specified by the language if the AA can become null again, after removing the last item?)
> 
> Second, I didn't test this in other OSes, but assuming the bug is reproducible, am I actually the first one to trip on this issue? It seems too basic, but I didn't find a duplicate in the bug database.

The problem is that you're using != with null. Don't do that. If you want to check whether something is null, use the is operator:

assert(a !is null);

If you use == or !=, it's going to do compare the objects, not their pointers/references, and in the case of an AA, that means that it's going to dereference them both and compare their contents. And since null is well, null, dereferencing it results in a segfault.

If you try and compare objects with null with ==, you get an error. The compiler should probably do the same with AAs but apparently doesn't.

So, if there's a bug, it's the fact that the compiler allows the comparison in the first place. Otherwise, there's no bug here.

- Jonathan M Davis
April 01, 2013
Oops, I knew that but totally forgot --;;
I shouldn't spend so much time without using D *shame*

Thanks!
April 01, 2013
On Mon, 01 Apr 2013 19:12:52 -0400, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Monday, April 01, 2013 22:32:01 =?UTF-8?B?Ikx1w61z?=.Marques
> <luismarques@gmail.com>@puremagic.com wrote:
>> I added a bug to the database, because the following code results
>> in a segfault (DMD v2.062, OS X 10.8.3, 64-bit):
>>
>> #!/usr/local/bin/rdmd
>>
>> @safe:
>>
>> void main()
>> {
>> int[string] a;
>> a["foo"] = 0;
>> a.remove("foo");
>> assert(a != null); // segfault (not exception)
>> }
>>
>> Now I come here for some further clarifications. While it seems
>> fairly clear to me that the assert should not crash the program
>> with a segmentation fault (at least with @safe), is the assert
>> actually true? (Is it even specified by the language if the AA
>> can become null again, after removing the last item?)
>>
>> Second, I didn't test this in other OSes, but assuming the bug is
>> reproducible, am I actually the first one to trip on this issue?
>> It seems too basic, but I didn't find a duplicate in the bug
>> database.
>
> The problem is that you're using != with null. Don't do that. If you want to
> check whether something is null, use the is operator:
>
> assert(a !is null);
>
> If you use == or !=, it's going to do compare the objects, not their
> pointers/references, and in the case of an AA, that means that it's going to
> dereference them both and compare their contents. And since null is well,
> null, dereferencing it results in a segfault.
>
> If you try and compare objects with null with ==, you get an error. The
> compiler should probably do the same with AAs but apparently doesn't.
>
> So, if there's a bug, it's the fact that the compiler allows the comparison in
> the first place. Otherwise, there's no bug here.
>

No, AA's are not classes (which BTW have had that problem fixed), they are pImpl structs.  The equals operator should check for null before comparing the contents.  It is a valid bug.

-Steve
April 01, 2013
On Monday, 1 April 2013 at 23:56:08 UTC, Steven Schveighoffer wrote:
> No, AA's are not classes (which BTW have had that problem fixed), they are pImpl structs.  The equals operator should check for null before comparing the contents.  It is a valid bug.

Baah, I had already closed the bug while cowering in shame! ;-)
April 02, 2013
Luís Marques:

> Baah, I had already closed the bug while cowering in shame! ;-)

Don't be ashamed for mistakes like this.

Bye,
bearophile
April 02, 2013
On Tue, Apr 02, 2013 at 01:57:14AM +0200, digitalmars-d-bounces@puremagic.com wrote:
> On Monday, 1 April 2013 at 23:56:08 UTC, Steven Schveighoffer wrote:
> >No, AA's are not classes (which BTW have had that problem fixed), they are pImpl structs.  The equals operator should check for null before comparing the contents.  It is a valid bug.
> 
> Baah, I had already closed the bug while cowering in shame! ;-)

So reopen it.


T

-- 
Spaghetti code may be tangly, but lasagna code is just cheesy.
April 02, 2013
On Tuesday, 2 April 2013 at 00:10:51 UTC, H. S. Teoh wrote:
> So reopen it.

bearophile already did. I just wanted the dust to settle, to see if there was consensus about it being a bug.
April 02, 2013
On Monday, 1 April 2013 at 23:56:08 UTC, Steven Schveighoffer wrote:
> No, AA's are not classes (which BTW have had that problem fixed), they are pImpl structs.  The equals operator should check for null before comparing the contents.  It is a valid bug.
>
> -Steve

This argument can be applied to classes too. I think it would be better to reject such code like in case with classes.
April 02, 2013
can we officially use

assert(a);

instead of

assert(a !is null);

(likewise with if(...))

It seems to compile and work just fine, and is shorter.
« First   ‹ Prev
1 2