[R-pkg-devel] Canonical way to Rprintf R_xlen_t
Ivan Krylov
kry|ov@r00t @end|ng |rom gm@||@com
Tue Nov 28 20:51:23 CET 2023
On Wed, 29 Nov 2023 06:11:23 +1100
Hugh Parsonage <hugh.parsonage using gmail.com> wrote:
> Rprintf("%lld", (long long) xlength(x));
This is fine. long longs are guaranteed to be at least 64 bits in size
and are signed, just like lengths in R.
> Rprintf("%td, xlength(x));
Maybe if you cast it to ptrdiff_t first. Otherwise I would expect this
to fail on an (increasingly rare) 32-bit system where R_xlen_t is int
(which is an implementation detail).
In my opinion, ptrdiff_t is just the right type for array lengths if
they have to be signed (which is useful for Fortran interoperability),
so Rprintf("%td", (ptrdiff_t)xlength(x)) would be my preferred option
for now. By definition of ptrdiff_t, you can be sure [*] that there
won't be any vectors on your system longer than PTRDIFF_MAX.
> using the string macro found in Mr Kalibera's commit of r85641:
> R_PRIdXLEN_T
I think this will be the best solution once we can afford
having our packages depend on R >= 4.4.
--
Best regards,
Ivan
[*] https://en.cppreference.com/w/c/types/ptrdiff_t posits that there
may exist long vectors that fit in SIZE_MAX (unsigned) elements but not
PTRDIFF_MAX (signed) elements. If such vector exists, subtracting two
pointers to its insides may result in undefined behaviour. This may be
already possible in a 32-bit process on Linux running with a 3G
user-space / 1G kernel-space split. The only way around the problem is
to use unsigned types for lengths, but that would preclude Fortran
compatibility.
More information about the R-package-devel
mailing list