diff --git a/NEWS.md b/NEWS.md index f9a44056..5b16fd54 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # cpp11 (development version) +* Fixed an rchk issue related to `std::initializer_list` (#457, @pachadotdev). + # cpp11 0.5.2 * Fixed an issue related to `-Wdeprecated-literal-operator` (#447, @andrjohns). @@ -12,7 +14,7 @@ * Because cpp11 now requires R >=4.0.0, a number of previously optional tools are now always available, allowing us to remove some dead code. In particular: - + * `R_UnwindProtect()` is always available, so the defines `HAS_UNWIND_PROTECT` and `CPP11_UNWIND` are no longer useful. diff --git a/inst/include/cpp11/list.hpp b/inst/include/cpp11/list.hpp index be29bb2a..6e7dd872 100644 --- a/inst/include/cpp11/list.hpp +++ b/inst/include/cpp11/list.hpp @@ -78,10 +78,9 @@ template <> inline r_vector::r_vector(std::initializer_list il) : cpp11::r_vector(safe[Rf_allocVector](VECSXP, il.size())), capacity_(il.size()) { - unwind_protect([&] { - SEXP names = Rf_allocVector(STRSXP, capacity_); - Rf_setAttrib(data_, R_NamesSymbol, names); + sexp names = safe[Rf_allocVector](STRSXP, capacity_); + unwind_protect([&] { auto it = il.begin(); for (R_xlen_t i = 0; i < capacity_; ++i, ++it) { @@ -92,6 +91,8 @@ inline r_vector::r_vector(std::initializer_list il) SET_STRING_ELT(names, i, name); } }); + + safe[Rf_setAttrib](data_, R_NamesSymbol, names); } typedef r_vector list; diff --git a/inst/include/cpp11/r_vector.hpp b/inst/include/cpp11/r_vector.hpp index 576f4fe6..1131b554 100644 --- a/inst/include/cpp11/r_vector.hpp +++ b/inst/include/cpp11/r_vector.hpp @@ -864,10 +864,9 @@ inline r_vector::r_vector(std::initializer_list il) valid_length(value, 1); } - unwind_protect([&] { - SEXP names = Rf_allocVector(STRSXP, capacity_); - Rf_setAttrib(data_, R_NamesSymbol, names); + sexp names = safe[Rf_allocVector](STRSXP, capacity_); + unwind_protect([&] { auto it = il.begin(); for (R_xlen_t i = 0; i < capacity_; ++i, ++it) { @@ -891,6 +890,8 @@ inline r_vector::r_vector(std::initializer_list il) SET_STRING_ELT(names, i, name); } }); + + safe[Rf_setAttrib](data_, R_NamesSymbol, names); } template diff --git a/tests/testthat/_snaps/register.md b/tests/testthat/_snaps/register.md index 37afbf49..aea86b76 100644 --- a/tests/testthat/_snaps/register.md +++ b/tests/testthat/_snaps/register.md @@ -1,4 +1,4 @@ -# get_call_entries: returns an empty string for packages with .Call entries and NAMESPACE files +# get_call_entries / returns an empty string for packages with .Call entries and NAMESPACE files Code call_entries @@ -11,7 +11,7 @@ [6] " {NULL, NULL, 0}" [7] "};" -# get_call_entries: works with multiple register functions. +# get_call_entries / works with multiple register functions. Code cat(read_file(cpp_bindings)) @@ -60,7 +60,7 @@ R_forceSymbols(dll, TRUE); } -# cpp_register: works with a package that registers a single c++ function +# cpp_register / works with a package that registers a single c++ function Code cat(read_file(r_bindings)) @@ -104,7 +104,7 @@ R_forceSymbols(dll, TRUE); } -# cpp_register: can be run with messages +# cpp_register / can be run with messages Code cpp_register(p, quiet = FALSE)