Skip to content

#1030 Bounds checking

Metadata

Property Value
Reported by Elias Pipping (elias.pipping@fu-berlin.de)
Reported at Jan 23, 2012 21:12
Type Bug Report
Version Git (pre2.4) [autotools]
Operating System Unspecified / All

Description

Transforming a mail I sent to the list, namely

http://lists.dune-project.org/pipermail/dune/2012-January/010085.html

into a bug so that the discussion can take place here.

Here's the original mail:

=========================

Hi,

I'd like to talk about classes like

  • FieldVector from dune/common/fvector.hh,
  • FieldMatrix from dune/common/fmatrix.hh
  • DiagonalMatrix from dune/istl/diagonalmatrix.hh

and the likes for a bit.

My understanding -- until I investigated a bit -- was that those classes do not perform any bounds checking by default and that defines like DUNE_FMatrix_WITH_CHECKING and DUNE_ISTL_WITH_CHECKING were there just for that(*).

Apparently, it's not that easy. And the fact that some classes contain specialisations for the case where they only store a single element from the underlying approximation of a field (e.g. double) is adding to the mess.

Here's a sample program.

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <dune/common/fmatrix.hh>
#include <dune/istl/diagonalmatrix.hh>

int
main()
{
  Dune::FieldVector<double,1> vec1;
  vec1[0] = 0;
  vec1[100] = 29;

  Dune::FieldVector<double,3> vec3;
  vec3[2] = 0;
  vec3[100] = 29;

  Dune::FieldMatrix<double,1,1> mat1;
  mat1[0][0] = 0;
  mat1[100][100] = 29;

  Dune::FieldMatrix<double,3,3> mat3;
  mat3[2][2] = 0;
  mat3[100][100] = 29;

  Dune::DiagonalMatrix<double, 1> diag1;
  diag1[0] = 0;
  diag1[100] = 29;
  diag1.diagonal(0) = 0;
  diag1.diagonal(100) = 29;

  Dune::DiagonalMatrix<double, 3> diag3;
  diag3[2] = 0;
  diag3[100] = 29;
  diag3.diagonal(2) = 0;
  diag3.diagonal(100) = 29;

  return 0;
}

The pattern is simple: For each of the aforementioned (three) classes, two objects are created -- once in three dimensions and once in 1D (to catch specialised implementations). Each construction is followed by one or multiple pairs of valid (=0) and invalid (=29) assignments (in that order);

All in all, there are eight invalid assignments in the above; which will be caught by default (ideal situation: none because bounds checking adds overhead) and how many are caught if both of the aforementioned defines are set? The current status appears to be:

  • 4/8 always fail
  • the aforementioned defines do not affect that number

Here is the body of the above program again, with annotations:

  Dune::FieldVector<double,1> vec1;
  vec1[0] = 0;
  //vec1[100] = 29;           // fails an assertion (fvector.hh:242)

  Dune::FieldVector<double,3> vec3;
  vec3[2] = 0;
  vec3[100] = 29;

  Dune::FieldMatrix<double,1,1> mat1;
  mat1[0][0] = 0;
  //mat1[100][100] = 29;      // fails an assertion (fmatrix.hh:279)

  Dune::FieldMatrix<double,3,3> mat3;
  mat3[2][2] = 0;
  //mat3[100][100] = 29;      // fails an assertion (fmatrix.hh:177)

  Dune::DiagonalMatrix<double, 1> diag1;
  diag1[0] = 0;
  //diag1[100] = 29;          // fails an assertion (fmatrix.hh:279)
  diag1.diagonal(0) = 0;
  diag1.diagonal(100) = 29;

  Dune::DiagonalMatrix<double, 3> diag3;
  diag3[2] = 0;
  diag3[100] = 29;
  diag3.diagonal(2) = 0;
  diag3.diagonal(100) = 29;

I've attached two patches (one to dune-common and one to dune-istl) that handle the other four cases with assertions that are guarded by DUNE_FMatrix_WITH_CHECKING; whether that is the correct define is questionable.

Whether the four cases whose assertions are not guarded by any defines (other than the absence of NDEBUG, naturally) should stay that way might be worth discussing as well.

For the discussion that led me to this investigation, see #1020 (closed).

Best regards,

Elias Pipping

(*) The latter is actually used in dune-common even if the name might suggest otherwise; The former can e.g. be found in ScaledIdentityMatrix::mv() from dune-istl, too;