mirror of https://github.com/CGAL/cgal
225 lines
8.6 KiB
TeX
225 lines
8.6 KiB
TeX
|
|
\ccSetThreeColumns{Failure_behaviour }{}{\hspace*{8.5cm}}
|
|
|
|
\section{Preconditions, Postconditions, Assertions and Warnings}
|
|
\label{sec:checks}
|
|
\ccIndexSubitem{checks}{preconditions}
|
|
\ccIndexSubitem{checks}{postconditions}
|
|
\ccIndexSubitem{checks}{assertions}
|
|
\ccIndexSubitem{checks}{warnings}
|
|
\ccIndexSubitemSeeAlso{preconditions}{checks}
|
|
\ccIndexSubitemSeeAlso{postconditions}{checks}
|
|
\ccIndexSubitemSeeAlso{assertions}{checks}
|
|
\ccIndexSubitemSeeAlso{warnings}{checks}
|
|
|
|
Much of the {\cgal} code contains checks.
|
|
For example, all checks used in the kernel code are prefixed by
|
|
\ccc{CGAL_KERNEL}.
|
|
Other packages have their own prefixes, as documented in the corresponding
|
|
chapters.
|
|
Some are there to check if the kernel behaves correctly, others are there to
|
|
check if the user calls kernel routines in an acceptable manner.
|
|
|
|
To assure that programs (and programmers) behave as expected,
|
|
the following four types of checks are used through the \cgal\ code:
|
|
\begin{description}
|
|
\item[Preconditions] check if the caller of a routine has called it in a
|
|
proper fashion. If such a check fails it is the responsibility of the caller
|
|
(usually the user of the library). Preconditions for functions and data
|
|
structures are documented in the corresponding reference pages.
|
|
\item[Postconditions] check if a routine does what it promises to do.
|
|
If such a check fails it is the fault of this routine. Postconditions
|
|
are also documented in the relevant sections of the reference manual.
|
|
\item[Assertions] are other checks that do not fit in the above two
|
|
categories. These are generally used to assure invariants in the
|
|
code and are not generally documented.
|
|
\item[Warnings] are checks for which it is not so severe if they fail.
|
|
\end{description}
|
|
|
|
By default, all of these checks are performed.
|
|
It is however possible to turn them off through the use of compile time
|
|
switches. The names of these switches for each of the above checks
|
|
are:
|
|
\begin{itemize}
|
|
\item \ccStyle{CGAL_<package>_NO_PRECONDITIONS},
|
|
\item \ccStyle{CGAL_<package>_NO_POSTCONDITIONS},
|
|
\item \ccStyle{CGAL_<package>_NO_ASSERTIONS} and
|
|
\item \ccStyle{CGAL_<package>_NO_WARNINGS}.
|
|
\end{itemize}
|
|
Here \ccc{<package>} stands for a string that is particular to each
|
|
package. This string should be documented at the beginning of the
|
|
chapter in this reference manual that includes the reference pages
|
|
for the function or data structure you are using.
|
|
|
|
For example, for the convex hull functions, the word
|
|
\ccc{CH} is used and thus the switches are:
|
|
\ccStyle{CGAL_CH_NO_PRECONDITIONS},
|
|
\ccStyle{CGAL_CH_NO_POSTCONDITIONS},
|
|
\ccStyle{CGAL_CH_NO_ASSERTIONS} and
|
|
\ccStyle{CGAL_CH_NO_WARNINGS}.
|
|
So, in order to compile the file \verb~foo.C~ with the postcondition checks
|
|
for these functions turned off, you should do:\\
|
|
\verb~CC -DCGAL_CH_NO_POSTCONDITIONS foo.C~
|
|
|
|
Not all checks are on by default.
|
|
All four types of checks can be marked as expensive or exactness checks
|
|
(or both).
|
|
These checks need to be turned on explicitly by supplying one or both of
|
|
the compile time switches \ccStyle{CGAL_<package>_CHECK_EXPENSIVE} and
|
|
\ccStyle{CGAL_<package>_CHECK_EXACTNESS}.
|
|
|
|
\ccIndexSubitemDef{checks}{expensive}
|
|
Expensive checks are, as the word says, checks that take a considerable
|
|
time to compute. Considerable is an imprecise phrase.
|
|
Checks that add less than 10 percent to the execution time of the routine
|
|
they are in are not expensive. Checks that can double the execution time are.
|
|
Somewhere in between lies the border line.
|
|
Checks that increase the asymptotic running time of an algorithm are always
|
|
considered expensive.
|
|
\ccIndexSubitemDef{checks}{exactness}
|
|
Exactness checks are checks that 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 doubles as number type, this may not
|
|
be the case, due to round off errors.
|
|
So, exactness checks should only be turned on if the computation is done
|
|
with some exact number type.
|
|
|
|
\section{Altering the Failure Behaviour}
|
|
\ccIndexSubitem{failure behaviour}{altering}
|
|
|
|
If a postcondition, precondition or assertion is
|
|
violated, the program will abort (stop and produce a core dump).
|
|
This behaviour can be changed by means of the following function.
|
|
|
|
\ccInclude{CGAL/assertions.h}
|
|
|
|
\ccGlueBegin
|
|
\ccGlobalFunction{Failure_behaviour
|
|
set_error_behaviour(Failure_behaviour eb);}
|
|
\ccGlueEnd
|
|
|
|
The parameter should have one of the following values.
|
|
|
|
\ccGlobalEnum{enum Failure_behaviour
|
|
{ ABORT, EXIT, EXIT_WITH_SUCCESS, CONTINUE };}
|
|
The first value is the default.
|
|
If the \ccStyle{EXIT} value is set, the program will stop and return a value
|
|
indicating failure, but not dump the core.
|
|
The last value tells the checks to go on after diagnosing the error.
|
|
|
|
\begin{ccAdvanced}
|
|
If the \ccStyle{EXIT_WITH_SUCCESS} value is set, the program will stop and
|
|
return a value corresponding to successful execution and not dump the core.
|
|
\end{ccAdvanced}
|
|
|
|
The value that is returned by \ccc{set_error_behaviour} is the value that
|
|
was in use before.
|
|
|
|
For warnings there is a separate routine, which works in the same way.
|
|
The only difference is that for warnings the default value is
|
|
\ccStyle{CONTINUE}.
|
|
|
|
\ccGlueBegin
|
|
\ccGlobalFunction{Failure_behaviour
|
|
set_warning_behaviour(Failure_behaviour eb);}
|
|
\ccGlueEnd
|
|
|
|
%\section{Control at a Finer Granularity}
|
|
%
|
|
%The compile-time flags as described up to now all operate on the whole
|
|
%library. Sometimes you may want to have a finer control.
|
|
%\cgal\ offers the possibility to turn checks on and off with a bit finer
|
|
%granularity, namely the module in which the routines are defined.
|
|
%The name of the module is to be appended directly after the \cgal\ prefix.
|
|
%So, the flag \ccStyle{CGAL_KERNEL_NO_ASSERTIONS} switches off assertions in
|
|
%the kernel only, the flag \ccStyle{CGAL_CH_CHECK_EXPENSIVE} turns on
|
|
%expensive checks in the convex hull module.
|
|
%The name of a particular module is documented with that module.
|
|
|
|
\begin{ccAdvanced}
|
|
|
|
\section{Customising how Errors are Reported}
|
|
\ccIndexSubitem{errors}{customized reporting of}
|
|
\ccIndexSubitem{warnings}{customized reporting of}
|
|
|
|
Normally, error messages are written to the standard error output.
|
|
It is possible to do something different with them.
|
|
To that end you can register your own handler.
|
|
This function should be declared as follows.
|
|
|
|
\ccTexHtml{\begin{samepage}}{}
|
|
\renewcommand{\ccLongParamLayout}{\ccTrue}
|
|
|
|
\lcTex{\ccAutoIndexingOff}
|
|
\ccGlobalFunction{
|
|
void my_failure_function( const char *type, const char *expression,
|
|
const char *file, int line, const char *explanation);}
|
|
\ccTexHtml{\end{samepage}}{}
|
|
\lcTex{\ccAutoIndexingOn}
|
|
|
|
Your failure function will be called with the following parameters:
|
|
\begin{description}
|
|
\item[\ccStyle{type}] is a string that contains one of the words
|
|
\texttt{precondition}, \texttt{postcondition}, \texttt{assertion} or
|
|
\texttt{warning}.
|
|
\item[\ccStyle{expression}] contains the expression that was violated.
|
|
\item[\ccStyle{file}] is the file in which the check was made.
|
|
\item[\ccStyle{line}] is the line number in that file on which the check
|
|
was made.
|
|
\item[\ccStyle{explanation}] contains an explanation of what was
|
|
checked. It can be \ccStyle{NULL}, in which case the
|
|
\ccStyle{expression} is thought to be descriptive enough.
|
|
\end{description}
|
|
|
|
There are several things that you can do with your own handler.
|
|
You can display a diagnostic message in a different way, for instance in
|
|
a pop-up window or to a log file (or a combination).
|
|
You can also implement a different policy on what to do after an error.
|
|
For instance, you can throw an exception or ask the user in a dialogue
|
|
whether to abort or to continue.
|
|
If you do this, it is best to set the error behaviour to
|
|
\ccStyle{CONTINUE}, so that it does not interfere with your policy.
|
|
|
|
You can register two handlers, one for warnings and one for errors.
|
|
Of course, you can use the same function for both if you want.
|
|
When you set a handler, the previous handler is returned, so you can restore
|
|
it if you want.
|
|
|
|
\ccInclude{CGAL/assertions.h}
|
|
|
|
\ccGlueBegin
|
|
\ccGlobalFunction{Failure_function
|
|
set_error_handler(Failure_function handler);}
|
|
|
|
\ccGlobalFunction{Failure_function
|
|
set_warning_handler(Failure_function handler);}
|
|
\ccGlueEnd
|
|
|
|
\subsubsection{Example}
|
|
|
|
\begin{cprog}
|
|
#include <CGAL/assertions.h>
|
|
|
|
void my_failure_handler(
|
|
const char *type,
|
|
const char *expr,
|
|
const char* file,
|
|
int line,
|
|
const char* msg)
|
|
{
|
|
/* report the error in some way. */
|
|
}
|
|
|
|
void foo()
|
|
{
|
|
CGAL::Failure_function prev;
|
|
prev = CGAL::set_error_handler(my_failure_handler);
|
|
/* call some routines. */
|
|
CGAL::set_error_handler(prev);
|
|
}
|
|
\end{cprog}
|
|
|
|
\end{ccAdvanced}
|
|
|