Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Member size() fails for Matrix objects #605

Closed
helmingstay opened this issue Dec 8, 2016 · 7 comments
Closed

Member size() fails for Matrix objects #605

helmingstay opened this issue Dec 8, 2016 · 7 comments

Comments

@helmingstay
Copy link

helmingstay commented Dec 8, 2016

Using Debian stretch, g++ 6.2.0-13, R version 3.3.2 (2016-10-31), Rcpp_0.12.8
Tested with NumericMatrix, Integer Matrix, LogicalMatrix

> sourceCpp('size.cpp')
size.cpp: In function ‘void test_mat(Rcpp::NumericMatrix)’:
size.cpp:13:18: error: request for member ‘size’ is ambiguous
     Rcout << obj.size();

size.cpp:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void test_vec(NumericVector obj){
    Rcout << obj.size();
    Rcout << obj.length();
}

// [[Rcpp::export]]
void test_mat(NumericMatrix obj){
    //problem:
    Rcout << obj.size();
    Rcout << obj.length();
}
@eddelbuettel
Copy link
Member

eddelbuettel commented Dec 8, 2016

Complete error (why oh why did you hide those?) from r-base Docker image using Debian testing, and fresh install of Rcpp 0.12.8 off CRAN:

> sourceCpp("size.cpp")
size.cpp: In functionvoid test_mat(Rcpp::NumericMatrix)’:
size.cpp:13:18: error: request for membersizeis ambiguous
     Rcout << obj.size();
                  ^~~~
In file included from /usr/local/lib/R/site-library/Rcpp/include/RcppCommon.h:165:0,
                 from /usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:27,
                 from size.cpp:1:
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/vector/MatrixBase.h:47:25: note: candidates are: R_xlen_t Rcpp::MatrixBase<RTYPE, na, MATRIX>::size() const [with int RTYPE = 14; bool na = true; MATRIX = Rcpp::Matrix<14>; R_xlen_t = long int]
         inline R_xlen_t size() const { return static_cast<const MATRIX&>(*this).size() ; }
                         ^~~~
In file included from /usr/local/lib/R/site-library/Rcpp/include/Rcpp/Vector.h:52:0,
                 from /usr/local/lib/R/site-library/Rcpp/include/Rcpp.h:40,
                 from size.cpp:1:
/usr/local/lib/R/site-library/Rcpp/include/Rcpp/vector/Vector.h:274:21: note:                 R_xlen_t Rcpp::Vector<RTYPE, StoragePolicy>::size() const [with int RTYPE = 14; StoragePolicy = Rcpp::PreserveStorage; R_xlen_t = long int]
     inline R_xlen_t size() const {
                     ^~~~
make: *** [size.o] Error 1
g++ -I/usr/share/R/include -DNDEBUG    -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp"   -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-3.3.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c size.cpp -o size.o
/usr/lib/R/etc/Makeconf:141: recipe for target 'size.o' failed
Error in sourceCpp("size.cpp") : 
  Error 1 occurred building shared library.
> 

Thoughts? Why did that bite us before? Matrix has always extended Vector. Weird...

@eddelbuettel
Copy link
Member

eddelbuettel commented Dec 8, 2016

This SO answer suggests leading the compiler to a preferred version of the ambiguous 'diamond pattern' call via a using class::memberfunc; declaration.

Anybody have experience with that? Had not seen the trick...

@eddelbuettel
Copy link
Member

That worked -- still in the same Docker container of r-base:

root@278c249b2281:/tmp# diff -ru Rcpp.orig/ Rcpp
diff -ru Rcpp.orig/inst/include/Rcpp/vector/Matrix.h Rcpp/inst/include/Rcpp/vector/Matrix.h
--- Rcpp.orig/inst/include/Rcpp/vector/Matrix.h 2016-11-13 21:30:50.000000000 +0000
+++ Rcpp/inst/include/Rcpp/vector/Matrix.h      2016-12-08 04:23:51.258459848 +0000
@@ -29,6 +29,7 @@
     int nrows ;
 
 public:
+    using Vector<RTYPE, StoragePolicy>::size;
     struct r_type : traits::integral_constant<int,RTYPE>{} ;
     struct can_have_na : traits::true_type{} ;
     typedef MatrixRow<RTYPE> Row ;
Only in Rcpp/src: api.o
Only in Rcpp/src: attributes.o
Only in Rcpp/src: barrier.o
Only in Rcpp/src: Date.o
Only in Rcpp/src: Module.o
Only in Rcpp/src: Rcpp_init.o
Only in Rcpp/src: Rcpp.so
root@278c249b2281:/tmp# 

Then:

root@278c249b2281:/tmp# Rscript -e 'library(Rcpp); sourceCpp("size.cpp")'
root@278c249b2281:/tmp# cat size.cpp 
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void test_vec(NumericVector obj){
    Rcout << obj.size();
    Rcout << obj.length();
}

// [[Rcpp::export]]
void test_mat(NumericMatrix obj){
    //problem:
    Rcout << obj.size();
    Rcout << obj.length();
}
root@278c249b2281:/tmp# 

We probably need more of these, but hey, it's a start.

@helmingstay
Copy link
Author

With the caveat that I'm well out of my depth...
For objects of class *Matrix (which inherit from Vector)

  • The intended behavior of length() and size() is the same?
  • length() works but size() doesn't
  • length() is defined only in Vector.h
  • size() is defined in Vector.h, VectorBase.h, and MatrixBase.h (but not Matrix.h)

@eddelbuettel
Copy link
Member

I looked at length() and size() recently and thought they were aliases everywhere. Maybe not...

@thirdwing
Copy link
Member

@helmingstay I think this is exactly the source of this error.

This should be fixed this (maybe other potential problems).

@eddelbuettel
Copy link
Member

With the caveat that I'm well out of my depth...

We all are :) Welcome to the C++ club.

@thirdwing Agreed. I should go to bed now; if you can find an alternate clean removing one of the redundant / ambiguous re-definitions -- which won't cause a failure elsewhere -- I'd like that. What I added feels ... like a bandaid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants