r-lib / cpp11

cpp11 helps you to interact with R objects using C++ code.
https://cpp11.r-lib.org/
Other
193 stars 46 forks source link

Creating a growing `list` with cpp11 results in elements with `R_NilValue`s at one point #344

Closed pepijn-devries closed 7 months ago

pepijn-devries commented 7 months ago

When adding integers of increasing length to a list, using push_back, the elements of the list become R_NilValue. Is this a bug in cpp11, or am I doing something wrong?

library(cpp11)
#> Warning: package 'cpp11' was built under R version 4.1.3

cpp_function("
sexp test() {
    writable::list result((R_xlen_t)0);
    for (int i = 0; i < 10; i++) {
      writable::integers x((R_xlen_t)0);
      for (int j = 0; j < i; j++) {
        x.push_back(j);
      }
      result.push_back(x);
    }
    return result;
  }
")

test()
#> [[1]]
#> integer(0)
#> 
#> [[2]]
#> [1] 0
#> 
#> [[3]]
#> [1] 0 1
#> 
#> [[4]]
#> [1] 0 1 2
#> 
#> [[5]]
#> [1] 0 1 2 3
#> 
#> [[6]]
#> [1] 0 1 2 3 4
#> 
#> [[7]]
#> [1] 0 1 2 3 4 5
#> 
#> [[8]]
#> [1] 0 1 2 3 4 5 6
#> 
#> [[9]]
#> [1] 0 1 2 3 4 5 6 7
#> 
#> [[10]]
#> [1] 0 1 2 3 4 5 6 7 8
#> 
#> [[11]]
#> NULL
#> 
#> [[12]]
#> NULL
#> 
#> [[13]]
#> NULL
#> 
#> [[14]]
#> NULL
#> 
#> [[15]]
#> NULL
#> 
#> [[16]]
#> NULL

Created on 2023-11-27 with reprex v2.0.2

R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default

locale:
[1] LC_COLLATE=Dutch_Netherlands.1252  LC_CTYPE=Dutch_Netherlands.1252    LC_MONETARY=Dutch_Netherlands.1252
[4] LC_NUMERIC=C                       LC_TIME=Dutch_Netherlands.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] cpp11_0.4.3    

loaded via a namespace (and not attached):
 [1] rstudioapi_0.13  knitr_1.42       magrittr_2.0.3   tidyselect_1.2.0 R6_2.5.1         rlang_1.1.0     
 [7] fastmap_1.1.0    fansi_1.0.3      decor_1.0.1      dplyr_1.1.2      tools_4.1.1      xfun_0.41       
[13] utf8_1.2.2       cli_3.4.1        clipr_0.7.1      withr_2.5.0      htmltools_0.5.4  yaml_2.3.7      
[19] digest_0.6.31    rprojroot_2.0.3  tibble_3.2.1     lifecycle_1.0.3  brio_1.1.3       processx_3.8.1  
[25] purrr_1.0.1      callr_3.7.3      tidyr_1.3.0      fs_1.6.2         vctrs_0.6.2      ps_1.6.0        
[31] evaluate_0.21    glue_1.6.2       rmarkdown_2.22   reprex_2.0.2     compiler_4.1.1   pillar_1.9.0    
[37] desc_1.4.2       generics_0.1.3   pkgconfig_2.0.3 
pepijn-devries commented 7 months ago

Never mind. The problem was that I was using the generic return type sexp. When I changed it to writable::list it worked

library(cpp11)

cpp_function("
writable::list test() {
    writable::list result((R_xlen_t)0);
    for (int i = 0; i < 10; i++) {
      writable::integers x((R_xlen_t)0);
      for (int j = 0; j < i; j++) {
        x.push_back(j);
      }
      result.push_back(x);
    }
    return result;
  }
")

test()