[R] C API - no NULL pointer guarantee?

Erez Shomron r-m@||@ @end|ng |rom erez@h@org
Sat Jul 27 13:36:20 CEST 2024


Hello,

I'm working on bindings for the API (for zig), and was wondering if the R's C API guarantees it won't return null pointers?
The only reference I found in the "Writing R Extensions" manual where this not the case is `R_tryEval` and `R_tryEvalSilent`.
Otherwise it's unclear.

The reason I care about this is syntax. Because I don't know whether SEXPs are NULL or not, then I wrap the SEXP in an optional type, and the burden is on the user to either check or assert every time you want to handle an optional SEXP.
It's not too bad and provides null safety, but can get excessive.

See an example from one of my test functions (question mark unwraps the optional. asserting it is not null):
```
export fn testAsScalarVector() Robject {
    const results = rzig.vec.allocVector(.List, 23).?.protect();
    defer rzig.gc.protect_stack.unprotectAll();

    results.?.setListObj(0, rzig.vec.asScalarVector(@as(f32, 1.32456e+32)));
    results.?.setListObj(1, rzig.vec.asScalarVector(@as(f32, -9.87123e-32)));
    results.?.setListObj(2, rzig.vec.asScalarVector(math.inf(f32)));
    results.?.setListObj(3, rzig.vec.asScalarVector(-math.inf(f32)));
    results.?.setListObj(4, rzig.vec.asScalarVector(math.nan(f32)));

    results.?.setListObj(5, rzig.vec.asScalarVector(@as(f64, -9.1e+300)));
    results.?.setListObj(6, rzig.vec.asScalarVector(@as(f64, 1.2e-300)));
    results.?.setListObj(7, rzig.vec.asScalarVector(math.inf(f64)));
    results.?.setListObj(8, rzig.vec.asScalarVector(-math.inf(f64)));
    results.?.setListObj(9, rzig.vec.asScalarVector(math.nan(f64)));

    results.?.setListObj(10, rzig.vec.asScalarVector(-9.1e+307));
    results.?.setListObj(11, rzig.vec.asScalarVector(1.2e-307));
    results.?.setListObj(12, rzig.vec.asScalarVector(1.0e+500)); // Inf
    results.?.setListObj(13, rzig.vec.asScalarVector(-1.0e+500)); // -Inf

    results.?.setListObj(14, rzig.vec.asScalarVector(5));
    results.?.setListObj(15, rzig.vec.asScalarVector(-5));
    results.?.setListObj(16, rzig.vec.asScalarVector(@as(u32, 4)));
    results.?.setListObj(17, rzig.vec.asScalarVector(@as(i32, -4)));
    results.?.setListObj(18, rzig.vec.asScalarVector(@as(u0, 0)));
    results.?.setListObj(19, rzig.vec.asScalarVector(@as(u150, 2_000_000_000)));
    results.?.setListObj(20, rzig.vec.asScalarVector(@as(i150, -2_000_000_000)));
    results.?.setListObj(21, rzig.vec.asScalarVector(true));
    results.?.setListObj(22, rzig.vec.asScalarVector(false));

    return results;
}
```

It would be nice to be able to drop the question mark, but only if R guarantees null safety at the API level. Then I would declare optional return types only for documented cases like `R_tryEval`

Appreciate your time an help!
Thanks,
- Erez



More information about the R-help mailing list