[R-pkg-devel] Canonical way to Rprintf R_xlen_t

Tomas Kalibera tom@@@k@||ber@ @end|ng |rom gm@||@com
Tue Nov 28 22:48:01 CET 2023


On 11/28/23 20:51, Ivan Krylov wrote:
> 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.
Right, this has been my choice for R-devel, at least for now. It still 
has downsides. In principle, it is not guaranteed that ptrdiff_t won't 
become bigger than long long at some point (but it is extremely unlikely 
anyone would run into that in R ever with array indexes). Then, on the 
other hand, it may be a waste in some cases, ptrdiff_t is smaller and in 
theory the generated code may be faster in some cases (that of course 
wouldn't matter for errors or I/O, but maybe in theory it could with 
purely string operations).
>
>> 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.

Yes, that is fine, too, with the cast, as long as R_xlen_t is not bigger 
than ptrdiff_t. You would have a problem if it ever changed in R. I 
don't think it is likely, but, technically, the formal guarantees in the 
C standard about for which array indexing ptrdiff_t are somewhat weak, 
maybe we might need to change this to support bigger arrays or maybe use 
the type R_xlen_t also for something slightly different that needs to be 
bigger.

>> 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.

Yes, the goal was to allow most C99 way using this macro, so e.g.

Rprintf("my index %" R_PRIdXLEN_T "\n", xlength(x));

(note the space before and after the macro in concatenation to be C++ 
friendly). This doesn't have the limitations described before, but, 
there is a problem with translations. I am still looking into that, but 
from what I can tell, gettext doesn't make this possible. A good support 
would allow strings described this way and also translated this way, 
using the symbolic name of the macro, not the expansion.

But, unless you use gettext/translations, this last option is probably 
best. Yet you would have to define the macro if not defined to support R 
4.3 and older versions.

Tomas

>



More information about the R-package-devel mailing list