#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;