Re: [Rd] returning NULL from .Call call

From: Prof Brian Ripley <ripley_at_stats.ox.ac.uk>
Date: Tue 15 Mar 2005 - 23:58:09 GMT

On Tue, 15 Mar 2005, Oleg Sklyar wrote:

> Dear R developers,
>
> I've just encountered one "feature" of R-C extensions.

What feature is that? (It really is not clear from your description.)

NULL in R is expressed as R_NilValue in C. What did you do when `trying to return NULL'? NULL in C is not a valid value for a SEXP pointer, of course.

This is documented in `Writing R Extensions', and there are many examples of it around.

> If it is known, I would be thankful for any hints why it works this way
> (I found the way around, which is also mentioned here, but maybe it is
> not the best one). If it is however unknown, it might be considered for
> a "wish list".
>
> Consider a simple "aka" C function (the original implementation loads complex
> data structures and there could be other causes of trouble apart from
> non-existing files):
>
> SEXP loadData(SEXP fileName) {
> int* data = NULL;
> try {
> // try to open the file and read the data into 'data'
> } catch(...) {
> std::cout << "Load failed (ANY REASON) - returning NULL" << std::endl;
> return NULL;
> }
> // operation successful, but the size of data can be nil
> if(data == NULL)
> return NULL;
> SEXP result = allocVector(INTSXP, numOfDataPoints);
> PROTECT(result);
> // copy data from 'data' into 'result'
> delete[] data;
> UNPROTECT(1);
> return result;
> }
>
> This function will nicely return a data array if no load problems occur and
> data is more than nil. If it is not the case I would be happy to receive a
> NULL as indication that the function didn't succeed, which I can then check
> with is.nul(...). I would consider it logical for SEXP, which is a pointer
> (in this case to a non-existing structure). However, trying to return NULL
> causes 'Segmentation Fault' without any further message and R-session closes.
> The question is, what would be a working way to return anything like NULL,
> something to check with is.null(...)?
>
> Now the way around (just in case it might be of interest), slightly modified
> function returning numeric(0) on fail:
>
> SEXP loadData(SEXP fileName) {
> // prerecreate and protect a non-NULL return value: numeric(0)

> SEXP result = allocVector(INTSXP, 0);
> PROTECT(result);
> int* data = NULL;
> try {
> // try to open the file and read the data into 'data'
> } catch(...) {
> std::cout << "Load failed (ANY REASON) - returning NULL" << std::endl;
> // unprotect and return numeric(0)
> UNPROTECT(1);
> return result;
> }
> // operation successful, but the size of data can be nil
> // unprotect old value to enable garbage collector to kill it sooner or

> later
> UNPROTECT(1);
> if(data == NULL)
> return result;
> // recreate and protect the return value

> result = allocVector(INTSXP, numOfDataPoints);
> PROTECT(result);
> // copy data from 'data' into 'result'
> delete[] data;
> UNPROTECT(1);
> return result;
> }
>
> This function always has something to return and it works, but not really
> elegantly and returning wrong data when fails.
>
> Thanks in advance for any comments.
> Regards
> Oleg
>
> --
> Dr Oleg Sklyar
> European Bioinformatics Institute
> Wellcome Trust Genome Campus
> Hinxton, Cambridge, CB10 1SD
> England
> phone/fax +44(0)1223 49 4478/4468
> e-mail osklyar@ebi.ac.uk
>
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
R-devel@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Wed Mar 16 10:59:39 2005

This archive was generated by hypermail 2.1.8 : Mon 20 Feb 2006 - 03:21:01 GMT