[Rd] must .Call C functions return SEXP?

Andrew Piskorski atp at piskorski.com
Thu Oct 28 01:43:47 CEST 2010

For using R's .Call interface to C functions, all the examples I've
seen have the C function return type SEXP.  Why?  What does R actually
do with this return type?  What happens if I *don't* return a SEXP?

Reason I ask, is I've written some R code which allocates two long
lists, and then calls a C function with .Call.  My C code writes to
those two pre-allocated lists, thus, I thought I should NOT need to
return any SEXP from my C function.  However, if I do that, it
segfaults somewhere in "src/main/memory.c".

If I instead return the SEXP for one of my two result lists it appears
to work fine...  But of course I don't understand what's going on here
and so don't trust it.  The list SEXP I am returning was allocated by
R, not by my C code, so why does it make any difference whether my C
function returns it or not?

>From "src/main/names.c" I see that .Call is implemented by do_dotcall
in "src/main/dotcode.c".  I don't necessarily understand what that
really does, but AFAICT if my C function returns nothing, the
do_dotcall's retval should simply remain set to R_NilValue, which
should be fine.

I must be misunderstanding something here, but I don't know what, and
would definitely appreciate any help.  Thanks!

My R code looks like this:

  result.1 <- vector("list" ,1e6)
  result.2 <- vector("list" ,1e6)
  .Call("my_C_function", result.1, result.2, other.input)

My C code looks like this:

  SEXP result_v; 
  result_v = Rf_allocVector(REALSXP, 5); 
  SET_VECTOR_ELT(result_list_1, k1, result_v); 
  REAL(result_v)[0] = some_number; 
  REAL(result_v)[1] = another_number; 
  /* Also do the same sort of thing for result_list_2. */
  return(result_list_1);  /* Appears to work ok. */
  /* return; */  /* Segfaults. */

Andrew Piskorski <atp at piskorski.com>

More information about the R-devel mailing list