[Rd] Custom C finalizers for .Call

Andrew Piskorski atp at piskorski.com
Wed Nov 25 00:20:24 CET 2015


On Tue, Nov 24, 2015 at 12:10:12AM +0100, Jeroen Ooms wrote:

> Currently it is all to easy for package authors to introduce a memory
> leak or stack imbalance by calling Rf_error() or
> R_CheckUserInterrupt() in a way that skips over the usual cleanup
> steps.

I have a more modest request:  Please improve the documentation of
exactly what Rf_error() does and how it should be used!  E.g., does
calling it terminate execution of the C function from which it is
called, or not?  The docs below don't actually say:

  https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Error-handling
  https://cran.r-project.org/doc/manuals/r-devel/R-ints.html#Warnings-and-errors

The docs imply that these are "C-level equivalents" to the R stop()
function, which of course DOES terminate execution.  I believe
Rf_error() does also, but I really wish it was explicitly stated one
way or the other.

Grepping the R source, I never did find where Rf_error() is actually
implemented.  What am I missing?

In src/include/Rinternals.h, the implementation of error_return()
first calls Rf_error(msg) and then does a separate "return R_NilValue"
in the next statement.  So you might think that Rf_error() must NOT
terminate execution, otherwise why the extra return statement?  But it
also has a comment:

  /* return(.) NOT reached : for -Wall */

Meaning that that return statement is just to silence compiler
warnings, and is not supposed to be reached because Rf_error()
terminates execution.  But this is a ridiculously roundabout way to
infer what the behavior of Rf_error() is supposed to be...

-- 
Andrew Piskorski <atp at piskorski.com>



More information about the R-devel mailing list