Use safer r_memcpy() and r_memset() everywhere#1797
Conversation
|
Makes sense to me. Linking this discussion which also has relevant insights: Maybe also worth noting the other, much subtler segfault we observed (in an old version of Bioconductor's {IRanges}): SEXP lengths;
int upper_run;
int *lengths_elt = INTEGER(lengths);
upper_run = *lengths_elt;One might hope this would "just work" for length-0 SEXP unless |
|
Hm, maybe this can be reverted in favor of just using R's own https://stat.ethz.ch/pipermail/r-devel/2025-April/083995.html |
|
Isn't it bad to do |
|
Hm I see what you mean, however, I confirm that just using #include <R_ext/RS.h>
Memcpy(p_out, p_x, cpy_size)resolves my original issue with |
|
I think the synthesis is thus: |
|
Per usual, mildly horrifying C behavior // value of x doesn't change
y = sizeof(x++);but that does seem to work in our favor here |
|
I think I'm still slightly happier with And for scalars like But in general it does seem like |
FWIW that does get caught by a stingy compiler
Works for me. I had a look at switching to |
Closes #1793 (in favor of this more holistic approach)
See also r-lib/vctrs#1968, but here's the TLDR below:
R 4.5.0 enables
CATCH_ZERO_LENGTH_ACCESShere:https://github.com/r-devel/r-svn/blob/9976c3d7f08c754593d01ba8380afb6be803dde2/src/main/memory.c#L4137-L4150
That means
REAL()and friends now return an invalid pointer of(void *) 1on 0-length R objects. I am not sure what it was returning before.This does not prevent us from calling
REAL()on 0-length R objects. i.e. code like this is fine and safe:It's only if we try and use
p_xthat we may get in trouble on some platforms, like what @MichaelChirico reported. For example, with:In a sane world, these would be safe because C should handle "if the size is 0, do nothing". But on some platforms it can detect that
p_xis invalid memory, and we get yelled at. The most ergonomic solution for this is to implement "if the size is 0, do nothing" ourselves throughr_memcpy()andr_memset()helpers, which is what I've done here. I've used them everywhere (even on memory not necessarily owned by R) except in the vendored xxhash code (which looks to be safe anyways).