[Rcpp-devel] Is declaring an argument as a reference the same as declaring it a pointer?

Romain Francois romain at r-enthusiasts.com
Tue Mar 30 08:53:07 CEST 2010


Le 27/03/10 23:10, Douglas Bates a écrit :
>
> I am writing code to interface from Rcpp to the Lapack linear algebra
> code which is written in Fortran.
>
> Because Lapack is written in Fortran all arguments must be passed from
> C as pointers.  There are many examples of the C versions of the
> declarations in the file R_HOME/include/R_ext/Lapack.h where you will
> see that a common idiom is to pass a pointer to the contents of a
> matrix, a pointer to an integer giving the number of columns, the same
> for the number of rows, and a third pointer which is the "leading
> dimension of the array as declared in the calling program".  (If all
> this seems bizarre, be grateful that you never needed to learn to
> program in Fortran.)
>
> For example, the C declaration of dgemm, which computes C := alpha * A
> %*% B + beta * C, is
> /* DGEMM - perform one of the matrix-matrix operations    */
> /* C := alpha*op( A )*op( B ) + beta*C */
> void
> F77_NAME(dgemm)(const char *transa, const char *transb, const int *m,
> 		const int *n, const int *k, const double *alpha,
> 		const double *a, const int *lda,
> 		const double *b, const int *ldb,
> 		const double *beta, double *c, const int *ldc);
>
> The arguments m, n, k, alpha, lda, ldb, and beta are all int's or
> double's that must be passed as pointers.  If A, B and C are
> NumericMatrix objects then I need to write code like
>
>       const char *transa = "N", transb = "N";
>       const int m = A.nrow(), n = A.ncol(), ...
>       const double one = 1.0, zero = 0.0;
>
>       F77_CALL(dgemm)(transa, transb,&m,&n,&one, A.begin(),&m, ...)
>
> which is somewhat roundabout because I need to declare int's and
> double's and initialize them to fixed values so I can pass those fixed
> values as pointers for the Fortran routine.
>
> Can I declare a C++ interface replacing the const int *m, const double
> *alpha, etc. by
> const int&m, const double&alpha, etc. so that I can call the Fortran
> subroutine as
>
>      F77_CALL(dgemm)(transa, transb, A.nrow(), A.ncol(), 1.0,
> A.begin(), A.nrow(), ...

no. you have to do what you do above. references are not pointers. I 
guess you can do thing like :

F77_CALL(dgemm)(transa, transb,&(A.nrow()),&(A.ncol()), ...)

but I'd advise to stick to your current code which is easier to understand.

> In other words, do the formal argument declarations const int&m and
> const int *m both end up passing an address of an int, with the only
> difference being in what the form of the actual argument is?
>
> If so, is there any way to avoid the dance with the character strings?
>   It turns out that only the first character is ever examined in the
> Lapack code by I still need to pass an address to that character, not
> the character itself.

I don't think so (I have no clue about fortran however).

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7
`- http://tr.im/O1wO : highlight 0.1-5



More information about the Rcpp-devel mailing list