<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Mon, 26 Oct 2015 at 17:22 Elias Pipping <<a href="mailto:elias.pipping@fu-berlin.de">elias.pipping@fu-berlin.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Dear list,</div><div><br></div><div>I’m very confused and my impression is that at the bottom of my confusion lies something that’s not working the way it should. I’d appreciate it if you followed my journey and helped me to undo the knot in my head :)</div><div><br></div><div>To test bounds checking in dune-common I wrote a piece of code that I expected to compile but not run:</div><div><br></div><div>    Dune::FieldMatrix<double, 2, 3> A = {{1, 2, 3}, {10, 20, 30}};</div><div>    Dune::FieldMatrix<double, 3, 2> const B = {{1, 2}, {10, 20}, {100, 200}};</div><div>    A.rightmultiply(B);</div><div><br></div><div>Since rightmultiply (in contrast to rightmultiplyany) makes sense only if the matrix B is square, with a dimension that matches the number of columns of A, the above example is an incorrect use of this function: The result would be a 2x2 matrix yet rightmultiply() expects the resulting matrix to have the same shape as A (i.e. 2x3).</div><div><br></div><div>There are in fact two rightmultiply() functions: One in fmatrix.hh:</div><div><br></div><div>    FieldMatrix& rightmultiply (const FieldMatrix<K,cols,cols>& M)</div><div><br></div><div>This one requires B to be a FIeldMatrix of the right size. There’s another function in densematrix.hh</div><div><br></div><div>    template<typename M2></div><div>    MAT& rightmultiply (const DenseMatrix<M2>& M)</div><div><br></div><div>that does not have such a constraint, hence I expected the call A.rightmultiply(B) in my example to use this function. That’s not what happens, though. The DenseMatrix implementation is only used if I comment out the FieldMatrix implementation. I found this surprising: The FieldMatrix implementation obviously cannot be used. What happens instead (with the FieldMatrix implementation in place): Neither one is called. I get a segmentation fault instead (this is with clang 3.7, I have not tested any other compiler). I don’t understand why but apparently a cast of A to a 3x3 matrix is attempted, which fails, apparently in an infinite loop. A backtrace looks like this:</div><div><br></div><div>#0  0x0000000000407074 in Dune::(anonymous namespace)::DenseMatrixAssignerImplementation<Dune::FieldMatrix<double, 3, 3>, Dune::FieldMatrix<double, 3, 2>, false>::DefaultImplementation<Dune::FieldMatrix<double, 3, 3>, Dune::FieldMatrix<double, 3, 2>, false>::apply(Dune::FieldMatrix<double, 3, 3>&, Dune::FieldMatrix<double, 3, 2> const&) ()</div><div>#1  0x0000000000407094 in Dune::(anonymous namespace)::DenseMatrixAssignerImplementation<Dune::FieldMatrix<double, 3, 3>, Dune::FieldMatrix<double, 3, 2>, false>::DefaultImplementation<Dune::FieldMatrix<double, 3, 3>, Dune::FieldMatrix<double, 3, 2>, false>::apply(Dune::FieldMatrix<double, 3, 3>&, Dune::FieldMatrix<double, 3, 2> const&) ()</div><div><br></div><div>(over and over again)</div><div><br></div><div>A similar issue can be triggered with a simpler piece of code:</div><div><br></div><div>  using M23 = Dune::FieldMatrix<double, 2, 3>;</div><div>  using M32 = Dune::FieldMatrix<double, 3, 2>;</div><div>  M23 A = {{1, 2, 3}, {10, 20, 30}};</div><div>  M32 const B = {{1, 2}, {10, 20}, {100, 200}};</div><div>  M23 M(B);</div><div><br></div><div>This, too, gives me a segmentation fault, and the backtrace reveals a similar infinite loop:</div><div><br></div><div>0x0000000000406daa in Dune::(anonymous namespace)::DenseMatrixAssignerImplementation<Dune::FieldMatrix<double, 2, 3>, Dune::FieldMatrix<double, 3, 2>, false>::DefaultImplementation<Dune::FieldMatrix<double, 2, 3>, Dune::FieldMatrix<double, 3, 2>, false>::apply(Dune::FieldMatrix<double, 2, 3>&, Dune::FieldMatrix<double, 3, 2> const&) ()</div><div><br></div><div>It seems that the piece of code from densematrix.hh</div><div><br></div><div>      // static_cast                                                                              </div><div>      template< class M, class T ></div><div>      struct DefaultImplementation< M, T, false ></div><div>      {</div><div>        static void apply ( M &m, const T &t )</div><div>        {</div><div>          static_assert( (Conversion< const T, const M >::exists), "No template specialization of \</div><div>DenseMatrixAssigner found" );</div><div>          m = static_cast< const M & >( t );</div><div>        }</div><div>      };</div><div><br></div><div>calls itself over and over again because for some reason, the Conversion trait determines that </div><div>there is a conversion between Dune::FieldMatrix<double, 2, 3> and Dune::FieldMatrix<double, 3, 2> (as well as Dune::FieldMatrix<double, 3, 3> and Dune::FieldMatrix<double, 3, 2> in my original example). That doesn't seem correct to me... (is it?)</div><div><br></div><div>Now, of course in both cases I started out with an illegal piece of code. But somehow I expected the compiler to handle this more gracefully than with an infinite loop and a segfault. Is this a dune bug?</div></div><div dir="ltr"><div><br></div><div><br></div><div>Elias</div></div></blockquote><div><br></div><div>I've now turned this into</div><div><br></div><div>  <a href="https://gitlab.dune-project.org/core/dune-common/issues/5">https://gitlab.dune-project.org/core/dune-common/issues/5</a></div><div><br></div><div><br></div><div>Elias</div></div></div>