digitalmars.D - Empty associative array crashes program
- =?UTF-8?B?Ikx1w61z?= Marques" (22/22) Apr 01 2013 I added a bug to the database, because the following code results
- Jonathan M Davis (14/39) Apr 01 2013 The problem is that you're using != with null. Don't do that. If you wan...
- =?UTF-8?B?Ikx1w61z?= Marques" (3/3) Apr 01 2013 Oops, I knew that but totally forgot --;;
- Steven Schveighoffer (6/47) Apr 01 2013 No, AA's are not classes (which BTW have had that problem fixed), they a...
- =?UTF-8?B?Ikx1w61z?= Marques" (3/7) Apr 01 2013 Baah, I had already closed the bug while cowering in shame! ;-)
- bearophile (4/5) Apr 01 2013 Don't be ashamed for mistakes like this.
- H. S. Teoh (5/11) Apr 01 2013 So reopen it.
- =?UTF-8?B?Ikx1w61z?= Marques" (3/4) Apr 01 2013 bearophile already did. I just wanted the dust to settle, to see
- Maxim Fomin (4/9) Apr 01 2013 This argument can be applied to classes too. I think it would be
- Timothee Cour (6/6) Apr 01 2013 can we officially use
- Jonathan M Davis (7/18) Apr 02 2013 That depends on what a is. If it's an AA as in the OP, then yes, they sh...
- Timothee Cour (2/20) Apr 02 2013
- Steven Schveighoffer (12/20) Apr 02 2013 If you are saying you think AA's should reject the code when comparing t...
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): 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
Apr 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): 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
Apr 01 2013
Oops, I knew that but totally forgot --;; I shouldn't spend so much time without using D *shame* Thanks!
Apr 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: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. -SteveI added a bug to the database, because the following code results in a segfault (DMD v2.062, OS X 10.8.3, 64-bit): 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.
Apr 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! ;-)
Apr 01 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
Apr 01 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:So reopen it. T -- Spaghetti code may be tangly, but lasagna code is just cheesy.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! ;-)
Apr 01 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.
Apr 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. -SteveThis argument can be applied to classes too. I think it would be better to reject such code like in case with classes.
Apr 01 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.
Apr 01 2013
On Monday, April 01, 2013 23:44:43 Timothee Cour wrote: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.That depends on what a is. If it's an AA as in the OP, then yes, they should be the same. The same goes for a pointers to built-in types and arrays, but for classes and pointers to structs, assert(a) checks for null and then calls the class' invariant rather than just checking for null. However, the invariant does not get called for if statements. - Jonathan M Davis
Apr 02 2013
thanks I didn't know... must've been buried in the specs somewhere... On Tue, Apr 2, 2013 at 12:10 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Monday, April 01, 2013 23:44:43 Timothee Cour wrote: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.That depends on what a is. If it's an AA as in the OP, then yes, they should be the same. The same goes for a pointers to built-in types and arrays, but for classes and pointers to structs, assert(a) checks for null and then calls the class' invariant rather than just checking for null. However, the invariant does not get called for if statements. - Jonathan M Davis
Apr 02 2013
On Tue, 02 Apr 2013 01:22:26 -0400, Maxim Fomin <maxim maxim-fomin.ru> wrote:On Monday, 1 April 2013 at 23:56:08 UTC, Steven Schveighoffer wrote:If you are saying you think AA's should reject the code when comparing to null, then I don't agree. An AA is a struct, and a struct lives on the stack. It would be near impossible to make this work without arbitrary compiler help, and I don't see a reason to specifically add this. It's just as easy to check for null in opEquals. With classes there was NO way to intercept the comparison before the dereference, so the banning of == null was warranted (that situation has changed now that opEquals is a global runtime function, so this requirement is somewhat moot). -SteveNo, 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. -SteveThis argument can be applied to classes too. I think it would be better to reject such code like in case with classes.
Apr 02 2013