> hi. if i'm reading correctly, "Writing R Extensions" appears to be > inconsistent on the question of whether the arguments passed to a > routine called via .Call() or .External() should considered read-only.
There are two situations to consider. 1) You want to modify the arguments as a convenience in your computation, but in the end you will return information to the caller via the value returned from .Call. 2) You want to modify the arguments as a way of returning information to the caller. For instance: x <- numeric(100) # x contains zeros .Call("myfunction",x) # use new values now present in x For (1), if you want to modify a argument x, you just need to first check whether NAMED(x) is non-zero. If it is, you need to execute x=duplicate(x) (and probably PROTECT the result) before changing x. You can return x (the original or the duplicate) as the result of the .Call if you like, or just use it as an intermediate value in the computation. For (2), you need to be sure that the value passed to .Call is unshared. (Checking NAMED(x) and duplicating if it is non-zero won't work, since then the caller doesn't get to see the information put in the duplicate of x.) Unfortunately, there is no documentation on when objects are guaranteed to be unshared. The technique of (2) is used sometimes in standard R packages. For example, the "arima" function in the "stats" package calls ARIMA_Like and modifies its arguments as a way of returning information. It's presumably also used in many contributed packages. Since it's probably too much to eliminate all uses of (2), I think documentation on when an object is guaranteed to be unshared is needed. I propose that the following be guaranteed to produce an unshared object: 1) The vector creation functions: vector, numeric, integer, logical, complex, raw, and character. 2) The array creation functions: array and matrix. 3) The rep and rep.int functions, which are sometimes used in place of a vector creation function - eg, rep(0,10) rather than numeric(10). I think it should be assumed that any other function might return an unshared result (eg, 1-1 might return a shared zero object). Of course, the results from the above functions might become shared later, too (if assigned to more than one variable, for instance), but code like that above for .Call("myfunction",x) would be guaranteed to work. Radford Neal ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel