[Rcpp-devel] Casting error from checking package on CRAN under C++14, g++

Dirk Eddelbuettel edd at debian.org
Fri Jan 22 04:46:06 CET 2016

Hi Terrance,

On 21 January 2016 at 16:44, terrance savitsky wrote:
| Hi Rcpp experts, The CRAN maintainers inform me that when testing one of my
| packages under 
| g++ -std=gnu++14 (logs with gcc 5.3)
| that the following code snippet,
| IntegerVector dpr = diff(pr); /* pr is an Rcpp::IntegerVector */
| icolvec diffpersons(dpr.begin(), nc - 1, false);
| generates the following error:
| error: no matching function for call to ‘arma::Col<long long int>::Col(Rcpp::Vector<13>::iterator, int, bool)’
|      icolvec diffpersons(dpr.begin(), nc - 1, false);
| where I'm writing (the memory for) an Rcpp:: IntegerVector to an arma::icolvec. The default width for an Armadillo signed integer under C++11 and C++14 is 64-bit (long long).  I'd appreciate your insight on whether there is an alternate approach to casting an arma::icolvec from an Rcpp::IntegerVector that can deal with a 64-bit integer; for example, will as<icolvec>() work?

As you probably noticed, you were not the only one receiving this email.

To give you some background, the author of that very email insisted for many
years that the only actual C++ standard that mattered for R was C++98 (and
yes, it is referenced in the email) meaning that the interim C++03 changes
'never existed'.  This meant in particular that 'long long' was not
allowed. We have numerous #ifdef's around it because of that. Huge pain.

And so did Armadillo which you use.  Now if you check the Armadillo docs (as
I just had to as I had a very similar issue an older package of mine in the
same email), I saw in Conrad's docs (at http://arma.sourceforge.net/docs.html#Col)

  uword, sword
  uword is a typedef for an unsigned integer type; it is used for matrix
  indices as well as all internal counters and loops 

  sword is a typedef for a signed integer type

  The minimum width of both uword and sword is either 32 or 64 bits:
    when using the old C++98 / C++03 standards, the default width is 32 bits
    when using the new C++11 / C++14 standards, the default width is 64 bits on
       64-bit platforms (as of Armadillo 5.000) 

and that is key. Conrad now uses 64 bit (== long long) when C++11 or C++14 is
used.  So where you used to use the 'icolvec' before, you may now need
Col<int32_t> -- or else you will get a 'long long' when R wants an
'int'. Won't fly.

I just made that change in three spots in the package in question, and the
very error reported against my package goes away.  I started from a basic
Docker container providing on debian:unstable -- which I knew had g++-5.3 as
in the report we got -- and install R, Rcpp and RcppArmadillo after which
this was easy to test.

To be explicit, my diff was

diff --git a/src/devol.cpp b/src/devol.cpp
index 7b1ea80..ca4d063 100644
--- a/src/devol.cpp
+++ b/src/devol.cpp
@@ -32,13 +32,13 @@ void devol(double VTR, double f_weight, double f_cross, int i_bs_flag,
     const int urn_depth = 5;                    // 4 + one index to avoid 
     Rcpp::NumericVector par(i_D);               // initialize parameter vector to pass to evaluate function 
-    arma::icolvec::fixed<urn_depth> ia_urn2;    // fixed-size vector for urn draws
-    arma::icolvec ia_urntmp(i_NP);              // so that we don't need to re-allocated each time in permute
+    arma::Col<int32_t>::fixed<urn_depth> ia_urn2;    // fixed-size vector for urn draws
+    arma::Col<int32_t> ia_urntmp(i_NP);              // so that we don't need to re-allocated each time in permute
     arma::mat initialpop(i_D, i_NP); 
     int i_nstorepop = static_cast<int>(ceil(static_cast<double>((i_itermax - i_storepopfrom) / i_storepopfreq)));
     int p_NP = round(i_pPct * i_NP);            // choose at least two best solutions 
     p_NP = p_NP < 2 ? 2 : p_NP;
-    arma::icolvec sortIndex(i_NP);              // sorted values of ta_oldC 
+    arma::Col<int32_t> sortIndex(i_NP);         // sorted values of ta_oldC 
     if (i_strategy == 6) {
         for (int i = 0; i < i_NP; i++) 
             sortIndex[i] = i; 
edd at max:~/git/rcppde(feature/c++14)$ 

Hope this helps.


http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org

More information about the Rcpp-devel mailing list