www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - A very strange bug. DMD 2.058 64-bit Linux

reply Caligo <iteronvexor gmail.com> writes:
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<----------------

It took me a long time to pinpoint this because it's tricky to trigger the bug.

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

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.


Could someone else please confirm this behavior?
Feb 26 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 02/26/2012 09:06 PM, Caligo wrote:
 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]
I get: ... [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

 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.
I get: ... [4, 0, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 1, 0, 0, 1]
 Could someone else please confirm this behavior?
I have used DMD 2.058 64-bit linux.
Feb 26 2012
parent Caligo <iteronvexor gmail.com> writes:
Thanks.  I have reported the bug:
http://d.puremagic.com/issues/show_bug.cgi?id=7595
Feb 26 2012