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

Douglas Bates bates at stat.wisc.edu
Sat Mar 27 23:10:28 CET 2010


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(), ...

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.


More information about the Rcpp-devel mailing list