Sven Schönherr (sven@inf.ethz.ch)
Much of the CGAL code contains checks. Some are there to check if the code behaves correctly, others check if the user calls routines in an acceptable manner. We describe the different categories of checks (Section 5.1), the usage of checks (Section 5.2), and a more selective means of controlling checks (Section 5.3). Finally, a statement about exception handling is given (Section 5.4).
There are four types of checks.
The checks are implemented as preprocessor macros; i.e., CGAL_<check_type>(<Cond>) realizes a check of type <check_type> that asserts the condition <Cond>. For example,
CGAL_precondition( first != last);checks the precondition that a given iterator range is not empty. If the check fails, an error message similar to
CGAL error: precondition violation! Expr: first != last File: <file name> Line: <source code line>is written to the standard error stream and the program is aborted. If an additional explanantion should be given to the user, macros CGAL_<check_type>_msg(<Cond>,<Msg>) can be used. The text in <Msg> is just appended to the failure message given above.
In case a check is more complicated and the computation does not fit into a single statement, the additional code can be encapsulated using CGAL_<check_type>_code(<Code>). This has the advantage that the computation is not done if the corresponding category is disabled. For an example, suppose an algorithm computes a convex polygon. Thus we want to check the postcondition that the polygon is indeed convex, which we consider an expensive check. The code would look like this.
CGAL_expensive_postcondition_code( bool is_convex; ) CGAL_expensive_postcondition_code( /* compute convexity */ ) CGAL_expensive_postcondition_code( /* ... */ ) CGAL_expensive_postcondition_msg ( is_convex, \ "The computed polygon is NOT convex!" );
As already mentioned above, the standard checks are enabled by default. This can be changed through the use of compile-time flags. By setting the flag CGAL_NO_<CHECK_TYPE> all checks of type <CHECK_TYPE> are disabled, e.g. adding -DCGAL_NO_ASSERTIONS to the compiler call switches off all checks for assertions. To disable all checks in the library, the flag NDEBUG can be set (which also switches off the assert macro from the C-library) . The flag CGAL_NDEBUG disables all checks in CGAL but does not affect the standard assert macro.
To enable expensive and exactness checks, respectively, the compile-time flags CGAL_CHECK_EXPENSIVE and CGAL_CHECK_EXACTNESS have to be supplied. However, exactness checks should only be turned on if the computation is done with some exact number type.
The macros and related compile-time flags described so far all operate on the whole library. Sometimes the user may want to have a more selective control. CGAL offers the possibility to turn checks on and off on a per-package basis. Therefore a package-specific term is inserted in the macro names directly after the CGAL prefix, e.g., CGAL_kernel_assertion(<Cond>). Similarly, the uppercase term is used for the compile-time flags; e.g., CGAL_KERNEL_NO_WARNINGS switches off the warnings in only the kernel. Other packages have their own specific terms as documented in the corresponding chapters of the reference manual.
The documentation of your new package has to name the term chosen to be part of the package-specific macros in order to enable the user to selectively turn off and on the checks of your package. For example, in the documentation of the optimisation package you can find a sentence similar to the following.
The optimisation code uses the term OPTIMISATION for the checks; e.g., setting the compile time flag CGAL_OPTIMISATION_NO_PRECONDITIONS switches off precondition checking in the optimisation code.
Some parts of the library, e.g., the interval-arithmetic package, use exceptions, but there is no general policy concerning exception handling in CGAL.