The PlFail
class is used for short-circuiting a function
when failure or an exception occurs and any errors will be handled in
the code generated by the PREDICATE()
macro. See also
section 1.17.2).
For example, this code, using the C API:
PREDICATE(unify_zero, 1) { if ( !PL_unify_integer(A1.unwrap(), 0) ) return false; // could be an error or failure Sprintf("It's zero!\n"); return true; }
can instead be written this way, using the C++ API:
PREDICATE(unify_zero, 1) { PlCheckFail(A1.unify_integer(0)); Sprintf("It's zero!\n"); return true; }
Using throw PlFail()
in performance-critical code
can cause a signficant slowdown. A simple benchmark showed a 15x to 20x
slowdown using throw PlFail()
compared to return
false
(comparing the first code sample above with the second and
third samples; the speed difference seems to have been because in the
second sample, the compiler did a better job of inlining). However, for
most code, this difference will be barely noticeable. And if the code
usually succeeds, there is no significant difference.
There was no significant performance difference between the C++ version and this C version:
static foreign_t unify_zero(term_t a1) { return PL_unify_integer(a1, 0); }
If one of the C PL_*() functions in SWI-Prolog.h
returns
failure, this can be either a Prolog-style failure (e.g. from
PL_unify() or PL_next_solution()) or an error. If the
failure is due to an error, it's usually best to immediately return to
Prolog - and this can be done with the PlEx()
function, which turns a Prolog error into a C++ PlException
. PlCheckFail()
calls PlEx() and additionally throws PlFail()
if the failure is for Prolog failure.
PlEx() calls PL_exception()
to see if there is a Prolog exception; if so, the Prolog exception is
converted to a
PlException
object, which is then thrown. For more details
on the C++ exceptions, see section 1.15.
false
, throw PlFail
to
return control to Prolog with failure.PlException
if there was one; otherwise, return the rc.PlFail
to return control to Prolog with failure. This is the same as PlCheckFail()
except it can also specify a
qid_t
query ID.