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
* Depend on R >= 3.5.0 for `R_UnwindProtect()`
At this point in r-lib and the tidyverse we typically require R >= 3.6.0, so it is reasonable to finally require this and remove our suboptimal fallback paths.
* Remove `release_all()` and `CPP11_USE_PRESERVE_OBJECT`
Which no longer make sense if we have 1 preserve list per compilation unit and require R >=3.5.0.
It does not seem to be used by anyone.
* Update unwind-protect section of internals vignette
* NEWS bullet
Copy file name to clipboardExpand all lines: vignettes/internals.Rmd
+10-13Lines changed: 10 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -130,27 +130,24 @@ These functions are defined in [protect.hpp](https://github.com/r-lib/cpp11/blob
130
130
131
131
### Unwind Protect
132
132
133
-
In R 3.5+ cpp11 uses `R_UnwindProtect` to protect (most) calls to the R API that could fail.
133
+
cpp11 uses `R_UnwindProtect()` to protect (most) calls to the R API that could fail.
134
134
These are usually those that allocate memory, though in truth most R API functions could error along some paths.
135
-
If an error happends under `R_UnwindProtect` cpp11 will throw a C++ exception.
136
-
This exception is caught by the trycatch block defined in the `BEGIN_CPP11` macro in [cpp11/declarations.hpp](https://github.com/r-lib/cpp11/blob/main/inst/include/cpp11/declarations.hpp).
135
+
If an error happens under `R_UnwindProtect()`, cpp11 will throw a C++ exception.
136
+
This exception is caught by the try/catch block defined in the `BEGIN_CPP11` macro in [cpp11/declarations.hpp](https://github.com/r-lib/cpp11/blob/main/inst/include/cpp11/declarations.hpp).
137
137
The exception will cause any C++ destructors to run, freeing any resources held by C++ objects.
138
-
After the trycatch block exits the R error unwinding is then continued by `R_ContinueUnwind()` and a normal R error results.
138
+
After the try/catch block exits, the R error unwinding is then continued by `R_ContinueUnwind()` and a normal R error results.
139
139
140
-
In R versions prior to 3.5 `R_UnwindProtect()`is not available.
141
-
Unfortunately the options to emulate it are not ideal.
140
+
We require R >=3.5 to use cpp11, but when it was created we wanted to support back to R 3.3, but `R_ContinueUnwind()`wasn't available until R 3.5.
141
+
Below are a few other options we considered to support older R versions:
142
142
143
143
1. Using `R_TopLevelExec()` works to avoid the C long jump, but because the code is always run in a top level context any errors or messages thrown cannot be caught by `tryCatch()` or similar techniques.
144
144
2. Using `R_TryCatch()` is not available prior to R 3.4, and also has a serious bug in R 3.4 (fixed in R 3.5).
145
145
3. Calling the R level `tryCatch()` function which contains an expression that runs a C function which then runs the C++ code would be an option, but implementing this is convoluted and it would impact performance, perhaps severely.
146
-
4. Have `cpp11::unwind_protect()` be a no-op for these versions. This means any resources held by C++ objects would leak, including cpp11::r_vector / cpp11::sexp objects.
146
+
4. Have `cpp11::unwind_protect()` be a no-op for these versions. This means any resources held by C++ objects would leak, including `cpp11::r_vector` / `cpp11::sexp` objects.
147
147
148
-
None of these options is perfect, here are some pros and cons for each.
148
+
None of these options were perfect, here are some pros and cons for each.
149
149
150
150
1. Causes behavior changes and test failures, so it was ruled out.
151
-
2. Was also ruled out since we want to support back to R 3.3.
151
+
2. Was also ruled out since we wanted to support back to R 3.3.
152
152
3. Was ruled out partially because the implementation would be somewhat tricky and more because performance would suffer greatly.
153
-
4. is what we now do in cpp11. It leaks protected objects when there are R API errors.
154
-
155
-
If packages are concerned about the leaked memory they can call `cpp11::preserved.release_all()` as needed to release the current protections for all objects managed by cpp11.
156
-
This is not done automatically because in some cases the protections should persist beyond the `.Call()` boundry, e.g. in vroom altrep objects for example.
153
+
4. Is what we ended up doing before requiring R 3.5. It leaked protected objects when there were R API errors.
0 commit comments