Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

External pointers and attributes #308

Open
krlmlr opened this issue Mar 2, 2023 · 1 comment
Open

External pointers and attributes #308

krlmlr opened this issue Mar 2, 2023 · 1 comment

Comments

@krlmlr
Copy link
Member

krlmlr commented Mar 2, 2023

Invoking the move constructor of external_pointer<> clears attributes on an external pointer object.

I would expect the third and fourth output to be identical to the second output. A possible fix is duckdb/duckdb@12f6f10 (this project uses a vendored version of cpp11).

library(cpp11)

cpp_source(
  code = '
  #include "cpp11/external_pointer.hpp"
  #include "cpp11/strings.hpp"

  template <class X>
  cpp11::external_pointer<int> test_int() {
    X a = 0;
    auto p = cpp11::external_pointer<X>(&a, false);
    Rf_PrintValue(p);
    Rf_setAttrib(p, R_ClassSymbol, cpp11::writable::strings({"foo"}));
    Rf_PrintValue(p);

    return std::move(p);
  }

  [[cpp11::register]]
  SEXP test() {
    auto p = cpp11::sexp(test_int<int>());
    Rf_PrintValue(p);
    return p;
  }
  '
)

out <- test()
#> <pointer: 0x16f0af42c>
#> <pointer: 0x16f0af42c>
#> attr(,"class")
#> [1] "foo"
#> <pointer: 0x16f0af42c>
out
#> <pointer: 0x16f0af42c>

Created on 2023-03-02 with reprex v2.0.2

@stephematician
Copy link

In addition - there's some strange behaviour/errors that I couldn't pin down while moving duplicated external pointers around, e.g.

#include "cpp11.hpp"

using namespace cpp11;

[[cpp11::register]]
void cpp_death() {
    external_pointer<int> value_xptr(new int [8]);
    external_pointer<int> duplicate_xptr(value_xptr);
    value_xptr = std::move(duplicate_xptr);
}

It could be because external_pointer::r_deleter is called on the old_data (in external_pointer::reset) regardless of whether it should be called or not (I would have thought that r_deleter calls were managed by R when it finalised an EXTPTRSXP).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants