From ripley at stats.ox.ac.uk  Wed Mar 16 00:58:09 2005
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Wed Mar 16 00:58:18 2005
Subject: [Rd] returning NULL from .Call call
In-Reply-To: <42377062.4020702@ebi.ac.uk>
References: <42377062.4020702@ebi.ac.uk>
Message-ID: <Pine.LNX.4.61.0503152349580.17975@gannet.stats>

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


[Rd] returning NULL from .Call call
Prof Brian Ripley