Re: Sharing header files (was: Documenting the C API)

Radford Neal

Lukas wrote:

I think the goal should absolutely be that all implementations can
share a single set of header files.
I sort of agree, except that I think the shared header files are going
to be pretty small, consisting only of function prototypes and a few
global variables or constant definitions. The implementation-independent
header files would be included by the implementation-specific header
file that user code includes, which would have all the complicated

And it should be possible to compile a package against the header
files directly, without needing an implementation.
Only if we also provide a "stub" implementation, that defines things
like SEXP as a dummy type. Maybe this would be useful in checking
that user code isn't using some non-standard facility particular to
one implementation. Of course, the user code won't actually run.

Lukas writes:

- The header files do not expose any internals, like the internal
structure of a SEXP.
I agree, for the few, small header files that are implementation

- ???#define??? is only used (if at all) for mapping between names,
anything that carries functionality is implemented as a
function. This prevents accidentally using macros as a lhs that
aren???t supposed to be used that way.
This gets into implementation specifics that we don't need to get into
for this working group. It's really up to the implementation what they
do in the implementation-specific header files.

By the way, in pqR, inappropriate use of macros on the lhs of an assignment
is prevented by definitions such as the following:

#define NOT_LVALUE(x) (0,(x))
#define CAR(e) NOT_LVALUE((e)->u.listsxp.carval)
#define CDR(e) NOT_LVALUE((e)->u.listsxp.cdrval)

This method revealed a bug in the testthat package (which used
FRAME(x)=y rather than SET_FRAME(x,y)).

- All global variables are also implemented as functions, e.g.,
R_NaInt(). For compatibility, this may be mapped via ???#define
R_NaInt Rf_NaInt()???.
In pqR, I tried making NA_INTEGER a constant, but this fails with
package RcppEigen, which assumes one can write &NA_INTEGER. We
might declare that to be disallowed, of course.

- The opaque definitions of SEXP, etc. can be replaced with real
definitions, so that the inline functions can reach the speed of
the current macro-based solution.

I think that these are issues that this working group doesn't need to
get into. Defining and documenting the API is enough. Finding ways
of automatically diagnosing errors in using the API is a separate


Join to automatically receive all group messages.