[Rcpp-devel] Casting error from checking package on CRAN under C++14, g++
Dirk Eddelbuettel
edd at debian.org
Sun Jan 24 16:33:54 CET 2016
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 at 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 | edd at debian.org
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
--
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
More information about the Rcpp-devel
mailing list