Bug 5442 – std.algorithm.sort problem with struct with char[10]
Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2011-01-10T10:43:00Z
Last change time
2014-02-16T14:26:12Z
Keywords
rejects-valid
Assigned to
nobody
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2011-01-10T10:43:13Z
This D2 program tries to sort in-place a dynamic array of Foo according to just the first int x field (the third sort works on the whole structs), but when T is a char the program doesn't compile:
import std.algorithm: sort, schwartzSort;
alias char T; // doesn't work
//alias int T; // works
struct Foo {
int x;
T[10] a;
}
void main() {
auto array = new Foo[10];
sort!("a.x > b.x")(array);
static bool myComp(Foo f1, Foo f2) { return f1.x < f2.x; }
sort!(myComp)(array);
sort(array);
}
DMD 2.051 prints:
...\dmd\src\phobos\std\conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) matches more than one template declaration, ...\dmd\src\phobos\std\conv.d(114):toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) and ...\dmd\src\phobos\std\conv.d(224):toImpl(T,S) if (isStaticArray!(S))
Comment #1 by lovelydear — 2012-04-22T14:40:11Z
dmd 2.059 gives:
PS E:\DigitalMars\dmd2\samples> rdmd bug.d
E:\DigitalMars\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(6802): Error: static assert "Invalid predicate passed to sort: a < b"
bug.d(16): instantiated from here: sort!("a < b",cast(SwapStrategy)0,Foo[])
PS E:\DigitalMars\dmd2\samples>
Which is a correct message for sort(array), as we didn't pass a comparison method for Foo structs.
If we comment out this line, everything compiles fine (but doesn't run as I expected, though), due to this :
import std.stdio;
struct Foo {
int x;
this(int x){this.x = x;}
}
void main() {
auto array = new Foo[10];
//for(int i = array.length; i > 1; i--) { array[i].x = i; }
auto i = array.length;
foreach(Foo f; array) { f.x = --i; write(f.x);}
writeln();
foreach(Foo f; array) { write(f.x);}
}
giving that:
PS E:\DigitalMars\dmd2\samples> rdmd -O bug.d
9876543210
0000000000
Comment #2 by lovelydear — 2012-04-22T14:59:01Z
(In reply to comment #1)
> (but doesn't run as I
> expected, though), due to this :
> import std.stdio;
>
> struct Foo {
> int x;
> this(int x){this.x = x;}
> }
> void main() {
> auto array = new Foo[10];
> //for(int i = array.length; i > 1; i--) { array[i].x = i; }
> auto i = array.length;
> foreach(Foo f; array) { f.x = --i; write(f.x);}
> writeln();
> foreach(Foo f; array) { write(f.x);}
> }
>
> giving that:
> PS E:\DigitalMars\dmd2\samples> rdmd -O bug.d
> 9876543210
> 0000000000
Never mind this part of the message, it's wrong code.
Comment #3 by xinok — 2013-12-27T11:07:29Z
(In reply to comment #0)
> This D2 program tries to sort in-place a dynamic array of Foo according to just
> the first int x field (the third sort works on the whole structs), but when T
> is a char the program doesn't compile:
>
>
> import std.algorithm: sort, schwartzSort;
> alias char T; // doesn't work
> //alias int T; // works
> struct Foo {
> int x;
> T[10] a;
> }
> void main() {
> auto array = new Foo[10];
> sort!("a.x > b.x")(array);
> static bool myComp(Foo f1, Foo f2) { return f1.x < f2.x; }
> sort!(myComp)(array);
> sort(array);
> }
>
Tested in DMD 2.064.2 and I'm unable to reproduce the bug. The final line fails to compile because Foo doesn't define opCmp, but everything else is fine. The default predicate for sort is "a < b" and comparing two structs using less-than requires defining opCmp.
Unless somebody else can reproduce this issue, I think we can close this bug report.
Comment #4 by peter.alexander.au — 2014-02-16T12:17:31Z
Are you happy this is fixed bearophile?
Comment #5 by bearophile_hugs — 2014-02-16T12:42:05Z
(In reply to comment #4)
> Are you happy this is fixed bearophile?
Yes, closed. The error message is clear:
...\dmd2\src\phobos\std\functional.d-mixin-102(102,1): Error: need member function opCmp() for struct Foo to compare
Comment #6 by peter.alexander.au — 2014-02-16T14:26:12Z
Changed to WORKSFORME so that it doesn't appear in the changelog for next update.