[Rcpp-devel] Compiler error I can't understand

Douglas Bates bates at stat.wisc.edu
Sat May 8 00:20:14 CEST 2010


The lme4a package (available only from R-forge at present) uses
facilities from the Matrix package and Rcpp.  The Matrix package
itself uses the CHOLMOD sparse matrix package written in C.  In the C
code the sparse matrix representations are defined as structs and
passed as pointers to such structs.  In lme4a I have source files
MatrixNs.h and MatrixNs.cpp that provide thin class wrappers around
these structs.  So the Matrix package header files define

#ifdef __cplusplus
#extern "C" {
#endif

typedef struct cholmod_sparse_struct {
  /* various members */
} cholmod_sparse;

typedef struct cholmod_common_struct {
 /* various members */
} cholmod_common;

typedef cholmod_sparse *CHM_SP;
typedef cholmod_common *CHM_CM;

CHM_SP M_cholmod_transpose(const CHM_SP, int, CHM_CM);

#ifdef __cplusplus
}
#endif

In MatrixNs.h I declare

cholmod_common c;
class chmSp : cholmod_sparse {
public:
   chmSp(Rcpp::S4);
   CHM_SP transpose(int) const;
}

with the definition in MatrixNs.cpp of

CHM_SP chmSp::transpose(int values) const {
   return M_cholmod_transpose(this, values, &c);
}

and consistently get it thrown back at me by the compiler because of
an illegal transformation from "const cholmod_sparse*" to
"cholmod_sparse*" in the line where I call M_cholmod_transpose.

This is severely impeding the development of the code because I can't
pass chmSp objects as const chmSp& (or, apparently equivalently, chmSp
const&) which could cause a lot of unnecessary copying.  Of course,
those sparse matrices are members of larger objects, etc. and right
now there is the possibility that everything is being copied
unnecessarily.

Should this be happening and if so, why?  I believe that the
declaration of M_cholmod_transpose in effect for this piece of code
has the first argument declared as const CHM_SP.  (As I said, the
original code did not have const in the declaration and I may have
only modified one of the declarations and somehow it is picking up
another.  As a last resort I have copied all the relevant files from
the Matrix installed package area to the lme4a source area in my local
copy just so I am certain of the declaration that is in effect.)

Is there something peculiar about using the wrapper class in the sense
that "this" is a pointer to a chmSp and I am using it as a
cholmod_sparse pointer?  Alternatively, is it something about using
the "this" pointer itself?

The compiler errors are of the form

MatrixNs.cpp: In member function ‘cholmod_sparse*
MatrixNs::chmSp::transpose(int) const’:
MatrixNs.cpp:286: error: invalid conversion from ‘const
cholmod_sparse*’ to ‘cholmod_sparse*’

Any suggestions would be gratefully accepted - especially if they
solve the problem :-)

If someone wants to look at the actual source files I will try to
create a stripped down example.  The version on R-forge doesn't show
exactly this structure because I don't want to leave a version up
there that doesn't compile.


More information about the Rcpp-devel mailing list