[Rcpp-devel] Const correctness of NumericVector iterators
Romain François
romain at r-enthusiasts.com
Sun Nov 30 13:41:33 CET 2014
And now sent a pull request. Not sure this will be merged in with the new commandment that « Thou shalt not break abi ».
See: https://github.com/RcppCore/Rcpp/pull/211
Romain
> Le 29 nov. 2014 à 13:52, Romain François <romain at r-enthusiasts.com> a écrit :
>
> Promoted this to an issue on github. https://github.com/RcppCore/Rcpp/issues/209
>
> Should not be very hard to fix, but this is indeed a bug. The code should not compile if Rcpp respected const correctness.
>
>> Le 26 nov. 2014 à 14:20, Martyn Plummer <plummerM at iarc.fr> a écrit :
>>
>> This is related to David Shih's thread about modifying input arguments
>> but I think it needs its own thread.
>>
>> I found a problem when I tried porting some Rcpp code to run outside of
>> Rcpp by providing my own NumericVector implementation based on STL
>> vectors. In Rcpp it is possible to obtain a non-constant iterator for a
>> constant vector, whereas STL does not allow this.
>>
>> In particular, it is possible to modify a const NumericVector. The
>> compiler allows this because the actual contents of the NumericVector
>> are in auxiliary memory. But this breaks the abstraction of the
>> NumericVector class.
>>
>> An example is given below. The "sumsquares" function calculates the sum
>> of squares of a vector. Internally, it calls the "workhorse" function,
>> which is declared to take a constant reference as an argument. So it
>> looks safe to pass the input vector to "workhorse" without copying.
>> However the implementation of "workhorse" does in fact alter the vector.
>>
>> ### BEGIN SS.cc
>> #include <Rcpp.h>
>>
>> using Rcpp::NumericVector;
>>
>> static double workhorse(NumericVector const &v);
>>
>> // [[Rcpp::export]]
>> double sumsquares(NumericVector v)
>> {
>> //Since workhorse takes a constant reference we think we do not need
>> //to copy v...
>> return workhorse(v);
>> }
>>
>> double workhorse(NumericVector const &v)
>> {
>> double y = 0;
>> for (NumericVector::iterator i = v.begin(); i != v.end(); ++i) {
>> double &x = *i;
>> //... but this function does alter its argument
>> x *= x;
>> y += x;
>> }
>> return y;
>> }
>> ### END SS.cc
>>
>> In R we have
>>
>>> library(Rcpp)
>>> sourceCpp("SS.cc")
>>> x <- c(1,2,3)
>>> sumsquares(x)
>> [1] 14
>>> x #is modified
>> [1] 1 4 9
>>
>> Martyn
>>
>>
>> -----------------------------------------------------------------------
>> This message and its attachments are strictly confidential. If you are
>> not the intended recipient of this message, please immediately notify
>> the sender and delete it. Since its integrity cannot be guaranteed,
>> its content cannot involve the sender's responsibility. Any misuse,
>> any disclosure or publication of its content, either whole or partial,
>> is prohibited, exception made of formally approved use
>> -----------------------------------------------------------------------
>> _______________________________________________
>> 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
>
> _______________________________________________
> 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
More information about the Rcpp-devel
mailing list