You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Somewhat related to a recent post on R-devel, some users will still try to use Rf_error() in C++ code using Rcpp. However, (as is documented) C++ destructors won't run when a longjmp occurs in cases like this. For example:
#include <Rcpp.h>
using namespace Rcpp;
struct A {
A() { Rprintf("A()\n"); }
~A() { Rprintf("~A()\n"); }
};
// [[Rcpp::export]]
SEXP uhoh() {
A a;
Rf_error("Oops!");
}
/*** R
uhoh()
*/
In this example, ~A() is never printed.
We could consider masking the definition of Rf_error() in these contexts. For example, something like:
#define Rf_error(...) \
static_assert(false, "Use of Rf_error() in C++ contexts is unwise: consider using Rcpp::stop() instead.");
There might also be a way to provide our own definition of Rf_error() that "masks" the version provided by R, but I wasn't able to find something immediately obvious.
Nice -- I very much like the idea of using a pragma here. Including a warning could also have other unexpected side effects (e.g. if the function calling Rf_error happened to be called with a condition handler active).
Is it worth considering a way for users to opt-out, in case they really do need to use Rf_error in some specific context?
We can also have the definition itself inside an #ifndef Rcpp_Leave_Rf_Error_Alone (or equivalent). I think that would be more in line with common practice.
This issue is stale (365 days without activity) and will be closed in 31 days unless new activity is seen. Please feel free to re-open it is still a concern, possibly with additional data.
We could warn now, warn with deprecation after January in 1.1.1, and remove next July in 1.1.2 ?
We could move faster too. For RcppArmadillo I am currently in the middle of two transitions (no more C++11, plus deprecations) and CRAN was on board with both (in fact did 'no more C++11' on its own). A hint from @kurthornik was to rank order by reverse dependency. I ended up preparing PRs or emailed patches for all with 'n_rev_dep > 0'. Sixty-plus packages.
A hint from @kurthornik was to rank order by reverse dependency.
Updated above.
We could warn now, warn with deprecation after January in 1.1.1, and remove next July in 1.1.2 ?
So you mean
warn now = just warn but without masking Rf_error?
warn with deprecation = warn and mask?
not sure what you mean by "remove". Or you mean mask here, and then I'm not getting the "with deprecation" part?
I'm ok with moving fast. Most of them are fixed by just calling compileAttributes(). The issue is that if we send PRs for those, the work will be undone unless they develop their packages with a development version of Rcpp.
So then the "softer" approach would be message() now instead of warning but we may also want to go for it. (After doing some more homework first, rev.deps, check with CRAN etc.)
I've filled a bunch of issues from the other.txt file above. Pending (leading number is the number of downstream deps):
These are yours, @eddelbuettel, but I didn't fill issues to avoid bombarding you. I can do that of course if you prefer to have these issues open to remind you about this.
n_deps package
===============
28 RcppGSL [ fixed version 0.3.14 on CRAN ][ was half a false positive but fix pushed ]
6 nanotime [ fixed version 0.3.13 on CRAN ][ fix in PR, merged ]
4 RProtoBuf [ fixed version 0.4.26 on CRAN ][ fix committed and pushed ]
2 RcppDE [ fixed version 0.1.9 on CRAN ][ fix committed and pushed ]
1 RcppBDT [ fixed version 0.2.8 on CRAN ][ fix committed and pushed ]
1 RInside [ false positive ][1]
0 RcppCNPy [ fixed version 0.2.15 on CRAN ][ fix committed and pushed ]
0 RcppClassicExamples [ fixed version 0.1.4 on CRAN ][ fix committed and pushed ]
[1] one match in plain C helper file used only in Windows case at startup
I haven't found a public repo for these, so we should email the maintainers. [UPDATE: email sent]
I can definitely deal with mine, but it may also be that your numbers are inflated between looking at CRAN releases and git repos. E.g. I just picked nanotime and I only have this one left (which may want to become (Rf_error(...)). Ditto for RcppGSL where I expected more. Care to share how you greped and counted?
These are number of downstream deps (to order by importance, as you suggested), not number of Rf_error calls.
BTW, in cases like the one in nanotime, this try then forward_exception_to_r construction is obsolete. C++ exceptions are correctly handled nowadays (i.e. catched and forwarded to R via Rcpp::stop automatically).
Did you point to public issue as a resource for them to consult, step to take to reproduce what you found to guide their development, other tips and tricks? (NM got the email now.)
I emailed the remaining ones with calls in RcppExports.cpp that can be solved by running compileAttributes() with a current version of Rcpp, and updated the repo above. Three cases are yours, @eddelbuettel:
RcppQuantuccia [ fixed on GitHub ]
RcppSpdlog [ fixed on GitHub ][ version 0.0.28 on CRAN ]
RQuantLib [ fixed on GitHub ][ ... regular April release expected... ]
Activity
kevinushey commentedon Oct 9, 2024
Nice -- I very much like the idea of using a pragma here. Including a warning could also have other unexpected side effects (e.g. if the function calling
Rf_errorhappened to be called with a condition handler active).Is it worth considering a way for users to opt-out, in case they really do need to use
Rf_errorin some specific context?Enchufa2 commentedon Oct 9, 2024
#undefis the way out. This of course should be documented.eddelbuettel commentedon Oct 9, 2024
We can also have the definition itself inside an
#ifndef Rcpp_Leave_Rf_Error_Alone(or equivalent). I think that would be more in line with common practice.github-actions commentedon Oct 11, 2025
This issue is stale (365 days without activity) and will be closed in 31 days unless new activity is seen. Please feel free to re-open it is still a concern, possibly with additional data.
Enchufa2 commentedon Oct 28, 2025
Pinging the bot over here so that the issue is not closed. I'll propose something soon.
Enchufa2 commentedon Oct 28, 2025
Rf_errorcalls inRcppExports.cpp: attributes.txtRf_error: other.txtTotal: 263 unique packages, because a few of them have them both.
eddelbuettel commentedon Oct 28, 2025
We could warn now, warn with deprecation after January in 1.1.1, and remove next July in 1.1.2 ?
We could move faster too. For RcppArmadillo I am currently in the middle of two transitions (no more C++11, plus deprecations) and CRAN was on board with both (in fact did 'no more C++11' on its own). A hint from @kurthornik was to rank order by reverse dependency. I ended up preparing PRs or emailed patches for all with 'n_rev_dep > 0'. Sixty-plus packages.
Thoughts?
Enchufa2 commentedon Oct 28, 2025
Updated above.
So you mean
Rf_error?I'm ok with moving fast. Most of them are fixed by just calling
compileAttributes(). The issue is that if we send PRs for those, the work will be undone unless they develop their packages with a development version of Rcpp.eddelbuettel commentedon Oct 28, 2025
Correction: There is indeed no 'remove'. We are adding a warning.
eddelbuettel commentedon Oct 28, 2025
So then the "softer" approach would be
message()now instead ofwarningbut we may also want to go for it. (After doing some more homework first, rev.deps, check with CRAN etc.)replace ::Rf_error() with Rcpp::stop()
Enchufa2 commentedon Feb 27, 2026
I've filled a bunch of issues from the
other.txtfile above. Pending (leading number is the number of downstream deps):Details
eddelbuettel commentedon Feb 27, 2026
I can definitely deal with mine, but it may also be that your numbers are inflated between looking at CRAN releases and git repos. E.g. I just picked
nanotimeand I only have this one left (which may want to become(Rf_error(...)). Ditto forRcppGSLwhere I expected more. Care to share how yougreped and counted?Enchufa2 commentedon Feb 27, 2026
These are number of downstream deps (to order by importance, as you suggested), not number of
Rf_errorcalls.BTW, in cases like the one in
nanotime, thistrythenforward_exception_to_rconstruction is obsolete. C++ exceptions are correctly handled nowadays (i.e. catched and forwarded to R viaRcpp::stopautomatically).eddelbuettel commentedon Feb 27, 2026
Ack re count, just maybe make it more explicit. I was about to ask you about that; RcppGSL has one instance of the same. Easy to fix.
Enchufa2 commentedon Feb 27, 2026
Email sent to the rest of the maintainers (in bcc).
eddelbuettel commentedon Feb 27, 2026
Did you point to public issue as a resource for them to consult, step to take to reproduce what you found to guide their development, other tips and tricks? (NM got the email now.)
Enchufa2 commentedon Feb 27, 2026
Yes, in the same way as the issues above. I sent the email to you, with everyone else in bcc.
eddelbuettel commentedon Feb 27, 2026
He did not link back by @t-kalinowski is already done as well: rstudio/reticulate#1888
Replace ::Rf_error with (Rf_error) in old demo code
Replace ::Rf_error by Rcpp::stop, as requested in RcppCore/Rcpp#1247.
Enchufa2 commentedon Mar 4, 2026
Repository with weekly updates on the status of afected packages: https://github.com/Enchufa2/Rcpp-mask-Rf_error
Enchufa2 commentedon Mar 5, 2026
I emailed the remaining ones with calls in
RcppExports.cppthat can be solved by runningcompileAttributes()with a current version of Rcpp, and updated the repo above. Three cases are yours, @eddelbuettel:Updates in relation to RcppCore/Rcpp#1247
Replace Rf_error with Rcpp::stop in ANN error handler
Fix Rf_error and future::availableCores issues (#2, #3)
Wrap Rf_error to avoid Rcpp macro interception
Bump version to 1.0.3 and note Rf_error fix
Favour Rcpp::stop() over Rf_error, to properly handle stack unwinding…
Parenthesize Rf_error to silence Rcpp scanner warning
Parenthesize Rf_error to silence Rcpp scanner warning
Bump Cuba and libcubature submodules for Rf_error fix