Exception handling
Overview
SeldonData uses exception handling to ease debugging and to make
codes safer. Macros TRY
and END
replace the
heavy structure try {
... catch() {...}
. For
all exceptions, the output is displayed on screen.
Options
Debugging options must be chosen before the library inclusion:
#define SELDONDATA_DEBUG_CHECK_INDICES #define SELDONDATA_DEBUG_CHECK_IO #define SELDONDATA_DEBUG_CHECK_DIMENSIONS #define SELDONDATA_DEBUG_CHECK_MEMORY #include "SeldonData.hxx" using namespace SeldonData;
The four debugging options are:
SELDONDATA_DEBUG_CHECK_MEMORY
, which checks memory allocations. It is advocated to set this option for all applications.SELDONDATA_DEBUG_CHECK_INDICES
, which checks all accesses. This leads to very safe but slow codes.SELDONDATA_DEBUG_CHECK_DIMENSIONS
, which checks dimensions compatibilities. Additional tests for this debugging option are associated with costly operations; it is advocated to set this option for all applications.SELDONDATA_DEBUG_CHECK_IO
, which checks input / output operations (on files). Since input / output operations are very slow, it is advocated to set this option for all applications.
Examples
Indices
#define SELDONDATA_DEBUG_CHECK_INDICES #include "SeldonData.hxx" using namespace SeldonData; int main() { TRY; RegularGrid<float> GridX(5); Data<double, 1, float> A(GridX); cout << "A(7) is:" << endl; cout << A(7) << endl; END; return 0; }
leads to:
A(7) is: ERROR! Index out of range in Data<T, 1>::operator(). Index along dimension #0 should be in [0, 4], but is equal to 7.
Dimensions
#define SELDONDATA_DEBUG_CHECK_DIMENSIONS #include "SeldonData.hxx" using namespace SeldonData; int main() { TRY; RegularGrid<int> GridX(5); Data<double, 3, int> A(GridX, GridX); END; return 0; }
leads to:
ERROR! Wrong dimension in Data<T, N, TG>::Data(Grid<TG>, ...). Required 3 grids, but got 2 grids. Aborted
IO
#define SELDONDATA_DEBUG_CHECK_IO #include "SeldonData.hxx" using namespace SeldonData; int main() { TRY; RegularGrid<double> GridX(5); Data<double, 1> A(GridX); FormatBinary<float> Input; Input.Read("ghost_file.bin", A); END; return 0; }
leads to:
ERROR! An input/output operation failed in FormatBinary<T>::Read(string FileName, Array<TA, N>& A). Unable to open file "ghost_file.bin".
Levels
As shown previously, one may choose what should be checked with the four previous flags. Alternatively, there are debug levels:
- SELDONDATA_DEBUG_LEVEL_0: nothing is checked.
- SELDONDATA_DEBUG_LEVEL_1: equivalent to SELDONDATA_DEBUG_CHECK_IO plus SELDON_CHECK_MEMORY.
- SELDONDATA_DEBUG_LEVEL_2: equivalent to SELDONDATA_DEBUG_LEVEL_1 plus SELDONDATA_DEBUG_CHECK_DIMENSIONS.
- SELDONDATA_DEBUG_LEVEL_3: equivalent to SELDONDATA_DEBUG_LEVEL_2 plus SELDONDATA_DEBUG_CHECK_INDICES.
- SELDONDATA_DEBUG_LEVEL_4: equivalent to SELDONDATA_DEBUG_LEVEL_3.
In practice, it is advocated to choose SELDONDATA_DEBUG_LEVEL_4 in the development stage and SELDONDATA_DEBUG_LEVEL_2 for the stable version. Indeed SELDONDATA_DEBUG_LEVEL_4 slows down the program but checks many things and SELDONDATA_DEBUG_LEVEL_2 should not slow down the program and ensures that it is quite safe.
Warning
SubData
may lead to "segmentation fault" if not
properly used. No exception will be raised if inputs of
SubData
are not correct...