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

Shallow duplicate in r_vector(const r_vector& rhs) constructor after all #387

Merged
merged 4 commits into from
Aug 21, 2024

Conversation

DavisVaughan
Copy link
Member

@DavisVaughan DavisVaughan commented Aug 21, 2024

Reverts part of #383, specifically the note here https://github.com/r-lib/cpp11/pull/383/files#r1723749948

We really do need to call Rf_shallow_duplicate() because we want ALL of the attributes on the rhs to get copied over, even dim and dimnames.

reserve_data() is meant to be used when we KNOW we have a vector that push_back() has been called on, which should hopefully never be a matrix (there is no matrix API for this). If that holds, then it is ok that the dim and dimnames attributes get dropped on growth (i.e. during a push_back()) and truncation (i.e. in the SEXP operator).

The downside of this comes up when you do: push_back(), then use the copy constructor, then return that value. The copy constructor retains all the extra capacity (meaning the allocation is larger than it maybe needs to be), and then when we return the value we also have to truncate. But this combination is probably somewhat rare, so its fine.


Without this, literanger breaks. We have now added tests to ensure we can't break this again accidentally.

The latter goes from `matrix -> SEXP -> r_vector` in a way that always avoids a copy, regardless of read-only or writable. This new way ensures that we go `r_vector -> r_vector`, and the correct `r_vector` constructor can get called. If its a writable input, it will be correctly copied now.
Otherwise treat it like other attributes that just get shallow copied over
…ructor after all

The fact that `reserve_data()` drops `dim` and `dimnames` unconditionally is problematic here, because this copy constructor gets called from inside the `matrix` class.

Really we should restrict usage of `reserve_data()` to JUST `reserve()`. This should be fine because it will only get called if we `push_back()`, and you can't `push_back()` on a `matrix`.
@DavisVaughan DavisVaughan merged commit 3706db2 into r-lib:main Aug 21, 2024
16 checks passed
@DavisVaughan DavisVaughan deleted the fix/clone-full-length branch August 21, 2024 20:33
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

Successfully merging this pull request may close these issues.

1 participant