[Rcpp-devel] Const correctness of NumericVector iterators
Romain Francois
romain at r-enthusiasts.com
Thu Nov 27 10:26:03 CET 2014
This is probably related to this:
template <int RTYPE>
struct r_vector_const_iterator {
typedef typename storage_type<RTYPE>::type* type ;
};
There should be a const there somewhere.
FWIW, more modern implementations of R/C++ are more safe on that issue:
$ Rcpp11Script /tmp/martyn.cpp
file33e7a74d9ba.cpp:18:33: error: cannot initialize a variable of type 'NumericVector::iterator' (aka 'double *') with an rvalue of
type 'const_iterator' (aka 'const double *')
for (NumericVector::iterator i = v.begin(); i != v.end(); ++i) {
^ ~~~~~~~~~
1 error generated.
make: *** [file33e7a74d9ba.o] Error 1
Error in dyn.load(basename(dynlib)) :
unable to load shared object '/private/var/folders/k8/gmp11jks4hl_nwcnk82fbr8m0000gn/T/RtmpKvVUpq/file33e7a74d9ba.so':
dlopen(/private/var/folders/k8/gmp11jks4hl_nwcnk82fbr8m0000gn/T/RtmpKvVUpq/file33e7a74d9ba.so, 6): image not found
Calls: sourceCpp -> <Anonymous> -> dyn.load
In addition: Warning message:
running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB 'file33e7a74d9ba.cpp'' had status 1
Execution halted
If I change NumericVector::iterator to auto, I then get:
$ Rcpp11Script /tmp/martyn.cpp
file34f617c08b2.cpp:19:16: error: binding of reference to type 'double' to a value of type 'const double' drops qualifiers
double &x = *i;
^ ~~
1 error generated.
make: *** [file34f617c08b2.o] Error 1
Error in dyn.load(basename(dynlib)) :
unable to load shared object '/private/var/folders/k8/gmp11jks4hl_nwcnk82fbr8m0000gn/T/Rtmp74ZJLp/file34f617c08b2.so':
dlopen(/private/var/folders/k8/gmp11jks4hl_nwcnk82fbr8m0000gn/T/Rtmp74ZJLp/file34f617c08b2.so, 6): image not found
Calls: sourceCpp -> <Anonymous> -> dyn.load
In addition: Warning message:
running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB 'file34f617c08b2.cpp'' had status 1
Execution halted
Hard compiler error/GOOD THING.
> 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
More information about the Rcpp-devel
mailing list