Terrance, On 21 January 2016 at 21:46, Dirk Eddelbuettel wrote: | | 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@max:~/git/rcppde(feature/c++14)$
A simpler fix might be to use this construct from the Armadillo header: #if defined(ARMA_32BIT_WORD) #undef ARMA_64BIT_WORD #endif I think that if you define ARMA_32BIT_WORD, but conditional on being in C++11/C++14 contexts, then the Armadillo should continue to use 32-bit integers which you can pass to R as before. That may be worth testing. Hope this helps, Dirk | Hope this helps. | | Dirk | | -- | http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org | _______________________________________________ | Rcpp-devel mailing list | Rcpp-devel@lists.r-forge.r-project.org | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel -- http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org _______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel