Calling R_ReleaseObject in a C++ destructor is not reliable - it can be bypassed by a non-local return, such as an error. Generally in R one cannot use C++ destructors reliably for anything that the R runtime wouldn't do on its own in case of a non-local return.

A destructor that calls just UNPROTECT, in a way that balances out the protection stack (e.g. Rcpp Shield), is safe because R runtime balances the protection stack on non-local return. Destructors used in code that will never call into any R API (such as in a third party library) are safe, because the R runtime could not do non-local return. All other destructors are a problem.

UNPROTECT will work even during R shutdown.

In some cases cleanup code that would be put in C++ destructors, if they were safe with R, can instead be put into R finalizers.

Tomas



On 09/21/2017 04:41 PM, Lukas Stadler wrote:
Hi!

We’ve recently come across an example where a package (minqa) creates an Rcpp 
Function object in a static variable.
This causes R_ReleaseObject to be called by the destructor at a very late point 
in time - as part of the system exit function:

static Function cf("c");

I’m wondering if that is considered to be “safe”?
Is the R engine supposed to stay in a state where calls to API functions are 
valid, even after it has shut down?
It probably only ever happens with the ReleaseObject function, but even that 
could cause problems, e.g., with more elaborate refcounting schemes.

- Lukas
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to