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

Tomas Kalibera tom@@@k@||ber@ @end|ng |rom gm@||@com
Tue Nov 28 23:20:51 CET 2023


On 11/28/23 21:55, Daniel Kelley wrote:
> I hope it's okay to ask this on the present thread, rather than starting a new one...
>
> On this issue of the C format for various integer-type items, I am finding that checks made with devtools::check_win_devel() give different results than those made with the github R-CMD-check action named ubuntu-latest-devel.  Which (if either) might be best for someone trying to fix up code for a CRAN release?
>
> # Details
>
> The code
>
> NumericVector a;
> ::R_error("size %ld", a.size());
>
> does not lead to warnings with R-CMD-check/ubuntu-latest-devel compilation, but it does with devtools::check_win_devel().  And the reverse is true with the code
>
> NumericVector a;
> ::R_error("size %lld", a.size());
>
> so one of these two methods must not be a good way to know if I'm doing the right thing.  I don't want to submit an update to CRAN that will lead to problems there, so I am keen to find a way to test this aspect without making a new submission (and thereby wasting time for the kind folks who run CRAN).

I think the best way to deal with these is to look at the lines and 
arguments identified by any of the compilers on any of the test 
platforms you have, and then based on reading the code and learning what 
the types really are (or are guaranteed to be) decide on how to fix. The 
presence and wording of the warnings may be compiler specific. In some 
cases even platform specific, because some C types have different size 
on different platforms, or map to different underlying types.

So, if the line above was identified by the compiler, check the 
documentation for NumericVector::size(), which type does it guarantee to 
return. The compiler warning may give a hint (what the type is in your 
build), but indeed it wouldn't consult the documentation. If the type is 
R_xlen_t (I didn't check if it is), then you could do e.g.

::R_error("size %lld", (long long)a.size());

or better

::R_error("size %" R_PRIdXLEN_T ", a.size());

as discussed elsewhere in this thread.

It is not a good idea to just use the type given in the warning, because 
that may not be portable. In this case, your compiler warning (on Linux) 
may have said "long int", which may have been how "ptrdiff_t" is defined 
on the platform by the compiler, which is probably how R_xlen_t is 
defined on your platform. But, it may be different elsewhere. On your 
second platform, the compiler warning may have said "long long int" (on 
Windows), which may have been how "ptrdiff_t" is defined there by the 
compiler, and on that platform, "long int" is different from "long long 
int", so the former didn't work.

If you use the Winbuilder service maintained by Uwe Ligges, you will 
have the same setup as one of the platforms used for CRAN incoming checks.

Best
Tomas

>
> Thanks.
>
> Dan.
>
>> On Nov 28, 2023, at 4:30 PM, Reed A. Cartwright <racartwright using gmail.com> wrote:
>>
>> CAUTION: The Sender of this email is not from within Dalhousie.
>>
>> If I have read the R's change log correctly, C99 printf format is now
>> supported on Windows. I think the change was made in the last week.
>>
>> On Tue, Nov 28, 2023, 13:01 Henrik Bengtsson <henrik.bengtsson using gmail.com>
>> wrote:
>>
>>> "%td" is not supported on all platforms/compilers.  This is what I got
>>> when I added it to 'matrixStats';
>>>
>>> * using log directory
>>> 'D:/a/matrixStats/matrixStats/check/matrixStats.Rcheck'
>>> * using R Under development (unstable) (2023-11-26 r85638 ucrt)
>>> * using platform: x86_64-w64-mingw32
>>> * R was compiled by
>>> gcc.exe (GCC) 12.3.0
>>> GNU Fortran (GCC) 12.3.0
>>> * running under: Windows Server 2022 x64 (build 20348)
>>> * using session charset: UTF-8
>>> * using options '--no-manual --as-cran'
>>> * checking for file 'matrixStats/DESCRIPTION' ... OK
>>> * this is package 'matrixStats' version '1.1.0-9003'
>>> * checking package namespace information ... OK
>>> * checking package dependencies ... OK
>>> * checking if this is a source package ... OK
>>> * checking if there is a namespace ... OK
>>> * checking for executable files ... OK
>>> * checking for hidden files and directories ... OK
>>> * checking for portable file names ... OK
>>> * checking serialization versions ... OK
>>> * checking whether package 'matrixStats' can be installed ... [22s] WARNING
>>> Found the following significant warnings:
>>> binCounts.c:25:81: warning: unknown conversion type character 't' in
>>> format [-Wformat=]
>>> binCounts.c:25:11: warning: too many arguments for format
>>> [-Wformat-extra-args]
>>> binMeans.c:26:60: warning: unknown conversion type character 't' in
>>> format [-Wformat=]
>>> binMeans.c:26:67: warning: unknown conversion type character 't' in
>>> format [-Wformat=]
>>> ...
>>> See 'D:/a/matrixStats/matrixStats/check/matrixStats.Rcheck/00install.out'
>>> for details.
>>> * used C compiler: 'gcc.exe (GCC) 12.2.0'
>>>
>>> It worked fine on Linux. Because of this, I resorted to the coercion
>>> strategy, i.e. "%lld" and (long long int)value.  FWIW, on MS Windows,
>>> I see 'ptrsize_t' being 'long long int', whereas on Linux I see 'long
>>> int'.
>>>
>>> /Henrik
>>>
>>> On Tue, Nov 28, 2023 at 11:51 AM Ivan Krylov <krylov.r00t using gmail.com>
>>> 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.
>>>>
>>>>> 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://urldefense.com/v3/__https://en.cppreference.com/w/c/types/ptrdiff_t__;!!IKRxdwAv5BmarQ!Zm84sWjl9Vg2_hQ8e5geMYnVFH8eNO-9KZsIkE7Tjk_V_-tj8W2Ept9o43gl-WGDczLbJTORU0oHTnfSA5iTLmO_uTKw$
>>> 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.
>>>>
>>>> ______________________________________________
>>>> R-package-devel using r-project.org mailing list
>>>>
>>> https://urldefense.com/v3/__https://stat.ethz.ch/mailman/listinfo/r-package-devel__;!!IKRxdwAv5BmarQ!Zm84sWjl9Vg2_hQ8e5geMYnVFH8eNO-9KZsIkE7Tjk_V_-tj8W2Ept9o43gl-WGDczLbJTORU0oHTnfSA5iTLmjE7gjq$
>>>
>>> ______________________________________________
>>> R-package-devel using r-project.org mailing list
>>>
>>> https://urldefense.com/v3/__https://stat.ethz.ch/mailman/listinfo/r-package-devel__;!!IKRxdwAv5BmarQ!Zm84sWjl9Vg2_hQ8e5geMYnVFH8eNO-9KZsIkE7Tjk_V_-tj8W2Ept9o43gl-WGDczLbJTORU0oHTnfSA5iTLmjE7gjq$
>>>
>>         [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> R-package-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>
> ______________________________________________
> R-package-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel



More information about the R-package-devel mailing list