As discussed here:
http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D.learn&artnum=33006
bug.d
---------------->8---------------->8----------------
@trusted:
import std.datetime : benchmark;
import std.stdio : writefln, writeln;
alias double Real;
void ben(alias fun)(string msg, uint n = 1_000_000) {
auto b = benchmark!fun(n);
writefln(" %s %s ms", msg, b[0].to!("msecs", int));
}
struct Matrix(int row, int col) {
private:
alias row Row;
alias col Col;
alias Real[Row * Col] Data;
public:
Data _data = void;
alias _data this;
this(const Real[Row*Col] data) pure nothrow { _data = data; }
}
M inverse(M)(const auto ref M m) {
writeln(m[]);
M minv = m;
return minv;
}
unittest {
alias Matrix!(4, 4) Matrix4x4;
auto m9 = Matrix4x4([4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0, 1]);
ben!( {auto r = inverse(m9);} )("4x4 inverse:");
}
----------------8<----------------8<----------------
t1.d
---------------->8---------------->8----------------
import std.stdio;
void main(){ }
----------------8<----------------8<----------------
Once you have those two files, compile with this:
dmd -unittest t1.d bug.d
and then run t1:
./t1
The output you get should look like this:
...
[0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0]
Obviously the output is wrong. 'm9' for some reason is getting
overwritten. In my project this caused big problems because there are
other m# with different values, and their values would literally get
copied to m9. Calling inverse() on m9 then would fail because the
other matrices are not invertible. Placing a writeln() in inverse()
helped me realize that what was being passed to inverse() was being
modified somewhere. I'm still now sure how m9 is being modified.
Another point, compiling with this:
dmd -unittest bug.d t1.d
and then running bug:
./bug
doesn't trigger the bug.
Comment #1 by luk.wrzosek — 2012-02-26T13:20:48Z
I can confirm this bug with dmd 2.058 32bit:
output with dmd -unittest bug.d t1.d:
[4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0, 1]
output with dmd -unittest t1.d bug.d:
[0, 5.31017e-315, 0, 0, 0, 0, 0, 5.30499e-315, 0, 0, 5.29981e-315, 5.30499e-315, 0, 5.29981e-315, 0, 0]
ldc and gdc, both work
Comment #2 by bugzilla — 2012-03-04T12:59:52Z
bug.d reduces to:
-----------------
@trusted:
import core.stdc.stdio;
import std.datetime : benchmark;
struct Matrix {
int[4] _data;
}
void inverse(const ref Matrix m) {
for (size_t i = 0; i < 4; i++)
printf("m._data[%d] = %d\n", i, m._data[i]);
}
unittest {
Matrix m9;
m9._data[0] = 1;
m9._data[1] = 2;
m9._data[2] = 3;
m9._data[3] = 4;
for (size_t i = 0; i < 4; i++)
printf("m9._data[%d] = %d\n", i, m9._data[i]);
benchmark!( { inverse(m9);} )(1);
}
Comment #3 by github-bugzilla — 2012-03-04T18:07:03Z