Hello,
here is yet another question. My C++ class A has lots of methods taking
Rcpp::NumericVectors as arguments. Since I also call these methods from
within C++, I would like to pass the arguments by 'const reference' and
not by value. Thus, I wrote methods with the following signature:
Rcpp::List A::foo(const Rcpp::NumericVector& v);
This seemed to work well for several methods. Then, however, I wrote a
constructor with signature
A::A(const Rcpp::NumericVector& v);
and exposed it via
.constructor<const Rcpp::NumericVector&>("test")
This code compiled without error, but unlike the previous methods, I got
strange results. When called from R, the vector 'v' contains random
values (like an uninitialized vector, or maybe an incorrectly casted
object) within the constructor.
My questions therefore are:
1. Is this a bug or are reference arguments not intended/not safe to
use/not allowed?
2. Is this unwanted behaviour restricted to constructors, or could it
also happen for other methods of the class?
3. Does the copy constructor for Rcpp::NumericVector actually create a
deep copy (duplicate elements)?
As always, I appreciate any assistance!
Best regards,
Peter
[Rcpp-devel] Const Reference Arguments for class methods in Rcpp-Module
4 messages · schattenpflanze at arcor.de, Dirk Eddelbuettel
Hi Peter,
On 23 April 2011 at 15:43, schattenpflanze at arcor.de wrote:
| here is yet another question. My C++ class A has lots of methods taking
| Rcpp::NumericVectors as arguments. Since I also call these methods from
| within C++, I would like to pass the arguments by 'const reference' and
| not by value. Thus, I wrote methods with the following signature:
|
| Rcpp::List A::foo(const Rcpp::NumericVector& v);
|
| This seemed to work well for several methods. Then, however, I wrote a
| constructor with signature
| A::A(const Rcpp::NumericVector& v);
| and exposed it via
| .constructor<const Rcpp::NumericVector&>("test")
|
| This code compiled without error, but unlike the previous methods, I got
| strange results. When called from R, the vector 'v' contains random
| values (like an uninitialized vector, or maybe an incorrectly casted
| object) within the constructor.
|
| My questions therefore are:
| 1. Is this a bug or are reference arguments not intended/not safe to
| use/not allowed?
| 2. Is this unwanted behaviour restricted to constructors, or could it
| also happen for other methods of the class?
| 3. Does the copy constructor for Rcpp::NumericVector actually create a
| deep copy (duplicate elements)?
Bugs do happen. You could have found a corner case. Few people may have
pushed the const variants around.
So with that we would appreciate it if you poked around a bit more and maybe
created an actual replicable bug report with a small self-contained example.
Also, a personal note if I may: I think of classes like Rcpp::NumericVector
more as 'facilitators': they make it very easy to get R data structures (in
SEXP) 'down' to C++ to do work on them, and back again. When I want to do
more work in C++ itself, I prefer to use actual C++ data structures and would
use Rcpp::NumericVector to instantiate, say, a std::vector<double> which
other C++ classes can access. If I am doing 'matrix math', the Armadillo
classes work well; for general C++ work the STL is trusted.
Hope this helps, Dirk
Gauss has an Erdos number of -1. -- #63 at http://www.gaussfacts.com
Hi Dirk,
Bugs do happen. You could have found a corner case. Few people may have pushed the const variants around. So with that we would appreciate it if you poked around a bit more and maybe created an actual replicable bug report with a small self-contained example.
Thank you for your reply. Is there a specific bug tracking site for
Rcpp? Meanwhile, I will post an example here. The following C++ code
defines two classes, A and B. Their constructors take a vector and print
it to the terminal. 'A' works with a const reference, 'B' takes the
argument by value.
--------------
C++ Code
--------------
#include <Rcpp.h>
using namespace Rcpp;
class A {
public:
A(const Rcpp::NumericVector& v) {
for (int i=0; i<v.size(); ++i) {
std::cout << v[i] << std::endl;
}
}
void foo(const Rcpp::NumericVector& v) {
for (int i=0; i<v.size(); ++i) {
std::cout << v[i] << std::endl;
}
}
};
class B {
public:
B(Rcpp::NumericVector v) {
for (int i=0; i<v.size(); ++i) {
std::cout << v[i] << std::endl;
}
}
};
RCPP_MODULE(TestMod) {
class_<A>( "A" )
.constructor<const Rcpp::NumericVector&>("Constructor A.")
.method("foo", &A::foo, "Print a vector.")
;
class_<B>( "B" )
.constructor<Rcpp::NumericVector>("Constructor B.")
;
}
------------
Loading the library and using the module in R yields the following:
------------
R session
------------
> a <- new(A, c(1,2,3))
4.68671e-318
> a$foo(c(1,2,3))
1
2
3
> b <- new(B, c(1,2,3))
1
2
3
-------------
Note that for the constructor of 'A', not even the size of the vector is
interpreted correctly. This may randomly lead to segfaults. The methods
A::foo() and B::B(), however, work as expected.
Also, a personal note if I may: I think of classes like Rcpp::NumericVector more as 'facilitators': they make it very easy to get R data structures (in SEXP) 'down' to C++ to do work on them, and back again. When I want to do more work in C++ itself, I prefer to use actual C++ data structures and would use Rcpp::NumericVector to instantiate, say, a std::vector<double> which other C++ classes can access. If I am doing 'matrix math', the Armadillo classes work well; for general C++ work the STL is trusted.
This is a very interesting topic. In fact, most of my code relies on STL containers directly. The class exposed to R is actually a facade for a pure virtual C++ class. Only within this facade, I use Rcpp::NumericVector. Many of the functions in the remaining code take iterator ranges. Thus, I can operate on Rcpp vectors or STL vectors without copying. Using const references in the exposed classes is not essential for my program. I did it out of a habit. I am worried about the fact that it compiles without error and yields somewhat undefined behaviour, though. Best regards, Peter
Hi Peter,
On 23 April 2011 at 17:04, schattenpflanze at arcor.de wrote:
| Hi Dirk,
|
| > Bugs do happen. You could have found a corner case. Few people may have
| > pushed the const variants around.
| > So with that we would appreciate it if you poked around a bit more and maybe
| > created an actual replicable bug report with a small self-contained example.
| Thank you for your reply. Is there a specific bug tracking site for
| Rcpp? Meanwhile, I will post an example here. The following C++ code
| defines two classes, A and B. Their constructors take a vector and print
| it to the terminal. 'A' works with a const reference, 'B' takes the
| argument by value.
|
| --------------
| C++ Code
| --------------
| #include <Rcpp.h>
| using namespace Rcpp;
|
| class A {
| public:
| A(const Rcpp::NumericVector& v) {
| for (int i=0; i<v.size(); ++i) {
| std::cout << v[i] << std::endl;
| }
| }
|
| void foo(const Rcpp::NumericVector& v) {
| for (int i=0; i<v.size(); ++i) {
| std::cout << v[i] << std::endl;
| }
| }
| };
|
| class B {
| public:
| B(Rcpp::NumericVector v) {
| for (int i=0; i<v.size(); ++i) {
| std::cout << v[i] << std::endl;
| }
| }
| };
|
| RCPP_MODULE(TestMod) {
| class_<A>( "A" )
| .constructor<const Rcpp::NumericVector&>("Constructor A.")
| .method("foo", &A::foo, "Print a vector.")
| ;
|
| class_<B>( "B" )
| .constructor<Rcpp::NumericVector>("Constructor B.")
| ;
| }
| ------------
|
| Loading the library and using the module in R yields the following:
|
| ------------
| R session
| ------------
| > a <- new(A, c(1,2,3))
| 4.68671e-318
| > a$foo(c(1,2,3))
| 1
| 2
| 3
| > b <- new(B, c(1,2,3))
| 1
| 2
| 3
| -------------
|
| Note that for the constructor of 'A', not even the size of the vector is
| interpreted correctly. This may randomly lead to segfaults. The methods
| A::foo() and B::B(), however, work as expected.
Thanks. Maybe Romain will have a chance to take a look in more detail.
| > Also, a personal note if I may: I think of classes like Rcpp::NumericVector
| > more as 'facilitators': they make it very easy to get R data structures (in
| > SEXP) 'down' to C++ to do work on them, and back again. When I want to do
| > more work in C++ itself, I prefer to use actual C++ data structures and would
| > use Rcpp::NumericVector to instantiate, say, a std::vector<double> which
| > other C++ classes can access. If I am doing 'matrix math', the Armadillo
| > classes work well; for general C++ work the STL is trusted.
| This is a very interesting topic. In fact, most of my code relies on STL
| containers directly. The class exposed to R is actually a facade for a
| pure virtual C++ class. Only within this facade, I use
| Rcpp::NumericVector. Many of the functions in the remaining code take
| iterator ranges. Thus, I can operate on Rcpp vectors or STL vectors
| without copying.
Right. Same idea for us with the proxy models around underlying SEXPs. It
should work that way.
| Using const references in the exposed classes is not essential for my
| program. I did it out of a habit. I am worried about the fact that it
| compiles without error and yields somewhat undefined behaviour, though.
Right. Thanks for the bug report.
Dirk
Gauss has an Erdos number of -1. -- #63 at http://www.gaussfacts.com