[R-pkg-devel] safely allocate SEXP and handle failure

Ivan Krylov kry|ov@r00t @end|ng |rom gm@||@com
Thu Sep 21 10:40:45 CEST 2023


On Thu, 21 Sep 2023 09:46:26 +0200
Jan Gorecki <j.gorecki using wit.edu.pl> wrote:

> I would like to safely allocate R object from C. By safely I mean
> that, I can test if allocation succeeded or failed, and then raise
> exception myself.
> R_alloc and allocVector both raises exception straightaway, so I am
> not able to handle failed allocation myself.

All R objects are subject to garbage collection (as potential garbage
or at least as a source of information about live objects), so they
have to be allocated by talking to the GC. (This also means that
R_alloc() is not a good way to create new SEXPs.)

It's not that it's impossible to return a failure code on allocation
failures instead of performing a longjmp() away from your code, but
since the rest of error handling in R works this way, extension code
has to always be ready to be longjmp()'d away from at every R API call.

How about catching the exception instead?

struct alloc_args { SEXPTYPE type; R_xlen_t len; };

static SEXP do_allocate(void * arguments) {
 struct alloc_args * args = arguments;
 return allocVector(args->type, args->len);
}

static SEXP maybe_allocate(SEXPTYPE type, R_xlen_t len) {
 struct alloc_args args = { .type = type, .len = len };
 return R_tryCatchError(do_allocate, &args, NULL, NULL);
} // returns R_NilValue on failure via the default tryCatch handler

Code is untested but should work according to WRE:
https://cran.r-project.org/doc/manuals/R-exts.html#Condition-handling-and-cleanup-code

-- 
Best regards,
Ivan



More information about the R-package-devel mailing list