cgal/Developers_manual/doc_tex/Developers_manual/checks.tex

267 lines
10 KiB
TeX

% =============================================================================
% The CGAL Developers' Manual
% Chapter: Checks: Pre- and Postconditions, Assertions, and Warnings
% -----------------------------------------------------------------------------
% file : checks.tex
% authors: Sven Schönherr <sven@inf.ethz.ch>
% -----------------------------------------------------------------------------
% $Id$
% $Date$
% =============================================================================
\index{preconditions!\seealso{checks}|none}
\index{postconditions!\seealso{checks}|none}
\index{assertions!\seealso{checks}|none}
\index{warnings!\seealso{checks}|none}
\chapter{Checks: Pre- and Postconditions, Assertions, and Warnings}
\label{chap:checks}
\ccIndexMainItemBegin{checks}
\ccChapterRelease{Chapter Version: 1.1}
\ccChapterAuthor{Sven Sch{\"o}nherr ({\tt 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~\ref{sec:checks_categories}), the usage of checks
(Section~\ref{sec:checks_using}), and a more selective means of controlling
checks (Section~\ref{sec:checks_controlling}). Finally, a statement
about exception handling is given
(Section~\ref{sec:exception_handling}).
% -----------------------------------------------------------------------------
\section{Categories of checks\label{sec:checks_categories}}
\ccIndexSubitemBegin{checks}{types of}
There are four types of checks.
%
\begin{itemize}
\item \textbf{Preconditions}\ccIndexMainItemDef{preconditions}
check if a routine has been called
in a proper fashion. If a precondition fails it is the
responsibility of the caller (usually the user of the library) to fix
the problem.
\item \textbf{Postconditions}\ccIndexMainItemDef{postconditions}
check if a routine does what it promises
to do. If a postcondition fails it is the fault of this routine, so
the author of the code is responsible.
\item \textbf{Assertions}\ccIndexMainItemDef{assertions}
are other checks that do not fit in the above
two categories, \eg~they can be used to check invariants.
\item \textbf{Warnings}\ccIndexMainItemDef{warnings}
are checks for which it is not so severe if they fail.
\end{itemize}
%
Failures of the first three types are errors and lead to a halt of the
program, failures of the last one only lead to a warning. Checks of
all four categories can be marked with one or both of the following
attributes.
%
\begin{itemize}
\item \emph{Expensive}\ccIndexSubitemDef{checks}{expensive}
checks take considerable time to compute.
``Considerable'' is an imprecise phrase. Checks that add less than 10
percent to the execution time of their routine are not expensive.
Checks that can double the execution time are. Somewhere in between
lies the border line.
\item \emph{Exactness}\ccIndexSubitemDef{checks}{exactness}%
\ccIndexSubitem{exactness}{checking}
checks rely on exact arithmetic. For example,
if the intersection of two lines is computed, the postcondition of
this routine may state that the intersection point lies on both
lines. However, if the computation is done with \ccc{double}s as
the number type, this may not be the case, due to roundoff errors.
\end{itemize}
%
\ccIndexSubitem{checks}{default}
By default, all standard checks (without any attribute) are enabled,
while expensive and exactness checks are disabled. How this can be
changed and how checks are actually used in the code are described in
the next section.
\ccIndexSubitemEnd{checks}{types of}
% -----------------------------------------------------------------------------
\section{Using checks\label{sec:checks_using}}
\ccIndexSubitemBegin{checks}{using}
The checks are implemented as preprocessor macros;
\ccIndexSubitem{macros}{for checks}
\ie,~\ccc{CGAL_<check_type>(<Cond>)} realizes a check of type \ccc{<check_type>}
that asserts the condition \ccc{<Cond>}. For example,
%
\begin{verbatim}
CGAL_precondition( first != last);
\end{verbatim}
%
checks the precondition that a given iterator range is not empty. If
the check fails, an error message similar to
%
\begin{verbatim}
CGAL error: precondition violation!
Expr: first != last
File: <file name>
Line: <source code line>
\end{verbatim}
%
is written to the standard error stream and the program is aborted. If
an additional explanantion should be given to the user,%
\ccIndexSubitem{checks}{adding failure message to}
macros \ccc{CGAL_<check_type>_msg(<Cond>,<Msg>)} can be used. The text in
\ccc{<Msg>} is just appended to the failure message given above.
\ccIndexSubitem{checks}{multiple-statement}
In case a check is more complicated and the computation does not fit
into a single statement, the additional code can be encapsulated using
\ccc{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.
%
\begin{verbatim}
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!" );
\end{verbatim}
\ccIndexSubitemBegin{checks}{disabling}
As already mentioned above, the standard checks are enabled by
default. This can be changed through the use of compile-time flags.
\ccIndexSubitem{compile-time flags}{for checks}
By setting the flag \ccc{CGAL_NO_<CHECK_TYPE>} all checks of type
\ccc{<CHECK_TYPE>} are disabled, \eg~adding \ccc{-DCGAL_NO_ASSERTIONS}%
\index{CGAL_NO_<CHECK_TYPE> flag@{\tt CGAL\_NO\_$<$CHECK\_TYPE$>$} flag}
to the compiler call switches off all checks for assertions. To disable
all checks in the library, the flag \ccc{NDEBUG}
\index{NDEBUG flag@{\tt NDEBUG} flag}
can be set (which also switches off the \ccc{assert} macro from the C-library)
\index{assert macro@{\tt assert} macro!disabling}.
\ccIndexSubitemEnd{checks}{disabling}
To enable expensive and exactness checks, respectively, the compile-time
flags \ccc{CGAL_CHECK_EXPENSIVE}%
\index{CGAL_CHECK_EXPENSIVE flag@{\tt CGAL\_CHECK\_EXPENSIVE} flag}
\ccIndexSubsubitem{checks}{expensive}{enabling}
and \ccc{CGAL_CHECK_EXACTNESS}
\index{CGAL_CHECK_EXACTNESS flag@{\tt CGAL\_CHECK\_EXACTNESS} flag}
\ccIndexSubsubitem{checks}{exactness}{enabling}
have to be supplied. However, exactness checks should only be turned on if
the computation is done with some exact number type.%
\ccIndexSubitem{exactness}{checking}
\ccIndexSubitemEnd{checks}{using}
% -----------------------------------------------------------------------------
\section{Controlling checks at a finer granularity\label{sec:checks_controlling}}
\ccIndexSubitemBegin{checks}{package-level}
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,
\eg,~\ccc{CGAL_kernel_assertion(<Cond>)}. Similarly, the uppercase
term is used for the compile-time flags;
\eg,~\ccc{CGAL_KERNEL_NO_WARNINGS} switches off the warnings
in \emph{only} the kernel. Other packages have their own specific
terms as documented in the corresponding chapters of the
reference manual.
\InternalOnly{
%
For a new package you will first have to create a suitable header file
with all macro definitions. This is done with the shell script
\texttt{create\_assertions.sh} (Section~\ref{sec:create_assertions}).
\index{create_assertions.sh script@{\tt create\_assertions.sh} script}
The following command will create a file {\tt optimisation\_assertions.h}.
{\centerline{\tt sh create\_assertions.sh optimisation}}
You should place the generated file in the proper directory (and possibly
rename it). Then you can use the checks in the following fashion.
\lcTex{
\begin{tabbing}
xxx\=xx\=\kill
\> \texttt{\#include $<$CGAL/optimisation\_assertions.h$>$} \\ \\
\> \texttt{void optimisation\_foo( int i)} \\
\> \texttt{\{} \\
\>\>\texttt{ CGAL\_optimisation\_precondition\_msg( i == 42, "Only 42 allowed!");} \\
\>\>\texttt{ // ...} \\
\> \texttt{\}}
\end{tabbing}
}
\lcHtml{
\begin{verbatim}
#include <CGAL/optimisation\_assertions.h>
void optimisation\_foo( int i)
{
CGAL_optimisation_precondition_msg( i == 42, "Only 42 allowed!");
// ...
}
\end{verbatim}
}
}
\ccIndexSubsubitem{checks}{package-level}{documenting}
\ccIndexSubitem{documentation}{of checks}
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.
\begin{quote}
The optimisation code uses the term OPTIMISATION for the checks;
\eg,~setting the compile time flag
\ccc{CGAL_OPTIMISATION_NO_PRECONDITIONS} switches off precondition
checking in the optimisation code.
\end{quote}
\ccIndexSubitemEnd{checks}{package-level}
% -----------------------------------------------------------------------------
\section{Exception handling\label{sec:exception_handling}}
\ccIndexMainItem{exception handling}
Some parts of the library, \eg,~the interval-arithmetic package, use
exceptions, but there is no general policy concerning exception
handling in \cgal.
\InternalOnly{
\section{Requirements and recommendations\label{sec:checks_req_and_rec}}
\noindent
Requirements:
\begin{itemize}
\item Write pre- and postcondition checkers for your functions wherever
possible.
\item Use the \cgal\ preprocessor macros (Sections~\ref{sec:checks_using}
and~\ref{sec:checks_controlling})
exclusively throughout your code (instead of,
for example, the \ccc{assert} macro) for all checks
to assure that all \cgal\ invariant tests can be handled in a uniform
way.
\end{itemize}
%\noindent
%Recommendations:
%\begin{itemize}
% \item
%\end{itemize}
}
\ccIndexMainItemEnd{checks}
% ===== EOF ===================================================================