[Rd] Questions on the R C API

Wang Jiefei @zwj|08 @end|ng |rom gm@||@com
Tue Nov 5 00:40:57 CET 2019

Hi Morgan,

My solutions might not be the best one(I believe it's not), but it should
work for your question.

1. Have you considered Rf_duplicate function? If you want to change the
value of `a` and reset it later, you have to have a duplication somewhere
for resetting it. Instead of changing the value of `a` directly, why not
changing the value of a duplicated `a`? So you do not have to reset it.

2. I think a pairlist behaves like a linked list(I might be wrong here and
please correct me if so). Therefore, there is no simple way to locate an
element in a pairlist. As for as I know, R defines a set of
convenient functions for you to access a limited number of elements. See

#define CAR(e) ((e)->u.listsxp.carval)
#define CDR(e) ((e)->u.listsxp.cdrval)
#define CAAR(e) CAR(CAR(e))
#define CDAR(e) CDR(CAR(e))
#define CADR(e) CAR(CDR(e))
#define CDDR(e) CDR(CDR(e))
#define CDDDR(e) CDR(CDR(CDR(e)))
#define CADDR(e) CAR(CDR(CDR(e)))
#define CADDDR(e) CAR(CDR(CDR(CDR(e))))
#define CAD4R(e) CAR(CDR(CDR(CDR(CDR(e)))))

You can use them to get first a few arguments from a pairlist. Another
solution would be converting the pairlist into a list so that you can use
the methods defined for a list to access any element. I do not know which C
function can achieve that but `as.list` at R level should be able to do
this job, you can evaluate an R function at C level and get the list
result( By calling `Rf_eval`). I think this operation is relatively low
cost because the list should only contain a set of pointers pointing to
each element. There is no object duplication(Again I might be wrong here).

3. You can get unevaluated expression at the R level before you call the C
function and pass it to your C function( by calling `substitute` function).
However, from my vague memory, the expression would be eventually evaluated
at the C level even you pass the expression to it. Therefore, I think you
can create a list of unevaluated arguments before you enter the C function,
so your C function can expect a list rather than a pairlist as its
argument. This can solve both your second and third questions.


On Mon, Nov 4, 2019 at 2:41 PM Morgan Morgan <morgan.emailbox using gmail.com>

> Hi All,
> I have some questions regarding the R C API.
> Let's assume I have a function which is defined as follows:
> R file:
> myfunc <- function(a, b, ...) .External(Cfun, a, b, ...)
> C file:
> SEXP Cfun(SEXP args) {
>   args = CDR(args);
>   SEXP a = CAR(args); args = CDR(args);
>   SEXP b = CAR(args); args = CDR(args);
>   /* continue to do something with remaining arguments in "..." using the
> same logic as above*/
>   return R_NilValue;
> }
> 1/ Let's suppose that in my c function I change the value of a inside the
> function but I want to reset it to what it was when I did SEXP a =
> CAR(args); . How can I do that?
> 2/Is there a method to set "args" at a specific position so I can access a
> specific value of my choice? If yes, do you have an simple example?
> 3/ Let's suppose now, I call the function in R. Is there a way to avoid the
> function to evaluate its arguments before going to the C call? Do I have to
> do it at the R level or can it be done at the C level?
> Thank you very much in advance.
> Best regards
> Morgan
>         [[alternative HTML version deleted]]
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

	[[alternative HTML version deleted]]

More information about the R-devel mailing list