www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Possible bug in std.algorithm.map

reply Magnus Lie Hetland <mlh idi.ntnu.no> writes:
Hi!

Just read Andrei Alexandrescu's new book, and I'm starting to  
experiment with using D in my algorithms research. Loved the book, and  
I'm loving the language so far :D

I just hit a snag, though ... I was doing something simple, for which  
my prototype code (in Python) was

   d, u = max((D(u,v), v) for v in V)

I first started writing it explicitly with loops, but it got a bit too  
verbose for my taste. Thought I'd use map and reduce, perhaps  
(although I'm still not sure if that's practical, as I'm reducing with  
max, but I'd like the argmax as well...).

Anyway -- while using attempting to use map, I suddenly got a  
segfault. As I hadn't really done any crazy stuff with pointers, or  
circumvented the bounds checks or the like, I was a bit surprised. I  
have now boiled things down to the following little program:

import std.algorithm;
void f() {
     auto x = 0;
     double g(int z) { // Alt. 1: return int
         auto y = x;   // Alt. 2: remove this
         return 0;
     }
     auto seq = [1, 2, 3];
     auto res = map!(g)(seq);
}
void main() {
     f();
}

When I compile and run this (dmd 2.051, OS X 10.5.8), I get a  
segmentation fault.

Oddly enough, if I *either* change the return type to int *or* remove  
the "y = x" line, things work just fine.

Am I correct in assuming this is a bug?

-- 
Magnus Lie Hetland
http://hetland.org
Jan 29 2011
next sibling parent Don <nospam nospam.com> writes:
Magnus Lie Hetland wrote:
 Hi!
 
 Just read Andrei Alexandrescu's new book, and I'm starting to experiment 
 with using D in my algorithms research. Loved the book, and I'm loving 
 the language so far :D
 
 I just hit a snag, though ... I was doing something simple, for which my 
 prototype code (in Python) was
 
   d, u = max((D(u,v), v) for v in V)
 
 I first started writing it explicitly with loops, but it got a bit too 
 verbose for my taste. Thought I'd use map and reduce, perhaps (although 
 I'm still not sure if that's practical, as I'm reducing with max, but 
 I'd like the argmax as well...).
 
 Anyway -- while using attempting to use map, I suddenly got a segfault. 
 As I hadn't really done any crazy stuff with pointers, or circumvented 
 the bounds checks or the like, I was a bit surprised. I have now boiled 
 things down to the following little program:
 
 import std.algorithm;
 void f() {
     auto x = 0;
     double g(int z) { // Alt. 1: return int
         auto y = x;   // Alt. 2: remove this
         return 0;
     }
     auto seq = [1, 2, 3];
     auto res = map!(g)(seq);
 }
 void main() {
     f();
 }
 
 When I compile and run this (dmd 2.051, OS X 10.5.8), I get a 
 segmentation fault.
 
 Oddly enough, if I *either* change the return type to int *or* remove 
 the "y = x" line, things work just fine.
 
 Am I correct in assuming this is a bug?
 

http://d.puremagic.com/issues/show_bug.cgi?id=5064 It's currently #8 on my list of most important bugs to fix in DMD.
Jan 29 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Sat, 29 Jan 2011 11:12:28 -0500, Magnus Lie Hetland <mlh idi.ntnu.no>  
wrote:

 Hi!

 Just read Andrei Alexandrescu's new book, and I'm starting to experiment  
 with using D in my algorithms research. Loved the book, and I'm loving  
 the language so far :D

 I just hit a snag, though ... I was doing something simple, for which my  
 prototype code (in Python) was

    d, u = max((D(u,v), v) for v in V)

 I first started writing it explicitly with loops, but it got a bit too  
 verbose for my taste. Thought I'd use map and reduce, perhaps (although  
 I'm still not sure if that's practical, as I'm reducing with max, but  
 I'd like the argmax as well...).

 Anyway -- while using attempting to use map, I suddenly got a segfault.  
 As I hadn't really done any crazy stuff with pointers, or circumvented  
 the bounds checks or the like, I was a bit surprised. I have now boiled  
 things down to the following little program:

 import std.algorithm;
 void f() {
      auto x = 0;
      double g(int z) { // Alt. 1: return int
          auto y = x;   // Alt. 2: remove this
          return 0;
      }
      auto seq = [1, 2, 3];
      auto res = map!(g)(seq);
 }
 void main() {
      f();
 }

 When I compile and run this (dmd 2.051, OS X 10.5.8), I get a  
 segmentation fault.

 Oddly enough, if I *either* change the return type to int *or* remove  
 the "y = x" line, things work just fine.

 Am I correct in assuming this is a bug?

Yes, it's Issue 5073. (http://d.puremagic.com/issues/show_bug.cgi?id=5073). I've tested your test case using the listed patch + DMD 2.051 and it works. The issue used to be a bad compile time error in earlier compiler versions but in DMD 2.051 it turned into a runtime error. The underlying error in DMD has to do with an alias of a delegate having a bad hidden pointer. The reason commenting out 'auto y = x;' works is that the incorrect hidden pointer is never called, thus never causing a segfault (IIRC). Issue 5073's patch works by passing delegates by value instead of by alias. Looking over Issue 5064, Don is probably right in it being the root cause in DMD, but if you just want map to work correctly, you might want to try the patch from 5073.
Jan 29 2011
prev sibling parent Magnus Lie Hetland <mlh idi.ntnu.no> writes:
On Jan 30, 2011, at 08:19 , Robert Jacques wrote:

 Yes, it's Issue 5073. (http://d.puremagic.com/issues/show_bug.cgi?id=5073 
 ).

OK.
 I've tested your test case using the listed patch + DMD 2.051 and it  
 works.

Great.
 Looking over Issue 5064, Don is probably right in it being the root  
 cause in DMD, but if you just want map to work correctly, you might  
 want to try the patch from 5073.

Thanks. I also see (from 5064) that using -inline works around the problem (worked for me). Slightly less invasive solution for right now, at least. Thanks for the help. -- Magnus Lie Hetland http://hetland.org
Jan 30 2011