Skip to content

Manage abort, assert, stderr, and stdout in C library for embedding it into R (and other similar environments) #3363

@gregorgorjanc

Description

@gregorgorjanc

One niggle I am encountering with building R package for exposing tskit C API (https://github.com/HighlanderLab/tskitr) is this kind of warning when running devtools::check() (we have to iron out all errors and warnings before eventual submission to CRAN):

...
── R CMD check results ──────────────────────── tskitr 0.0.1 ────
Duration: 30.8s

❯ checking compiled code ... WARNING
  File 'tskitr/libs/tskitr.so':
    Found '___assert_rtn', possibly from 'assert' (C)
      Objects: 'tskit/haplotype_matching.o', 'tskit/kastore.o',
        'tskit/tables.o', 'tskit/trees.o'
    Found '___stderrp', possibly from 'stderr' (C)
      Objects: 'tskit/core.o', 'tskit/genotypes.o',
        'tskit/haplotype_matching.o', 'tskit/tables.o', 'tskit/trees.o'
    Found '___stdoutp', possibly from 'stdout' (C)
      Object: 'tskit/core.o'
    Found '_abort', possibly from 'abort' (C)
      Objects: 'tskit/core.o', 'tskit/genotypes.o',
        'tskit/haplotype_matching.o', 'tskit/tables.o', 'tskit/trees.o'
  
  Compiled code should not call entry points which might terminate R nor
  write to stdout/stderr instead of to the console, nor use Fortran I/O
  nor system RNGs nor [v]sprintf.
  
  See 'Writing portable packages' in the 'Writing R Extensions' manual.

0 errors ✔ | 1 warning ✖ | 0 notes ✔
...

To replicate this warning follow https://github.com/HighlanderLab/tskitr/tree/main?tab=readme-ov-file#development. I have gathered some docs on this matter for myself at HighlanderLab/tskitr#5.

A standard way of dealing with this issue in R packages is to avoid crashing R session because the underlying process crashed and communicating abort/errors/warnings/messages to R session from the underlying process. I believe this is done using something like #ifdef R_BUILD (to be revised) and using Rcpp::stop for stderr (possibly also for assert though sometimes I see that in R packages these are removed from low-level code at compile time using -DNDEBUG - not sure if we should error though?, maybe using Rcpp::warning instead?) and similarly for stderr and stdout.

The above describes R way of doing things, but I wonder if we should be thinking of this more generally.

Any thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    C APIIssue is about the C API

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions