Skip to content

[Rcpp-devel] Bizarre Rcpp::XPtr problem on GCC

8 messages · Kevin Thornton, Dirk Eddelbuettel, Hao Ye +1 more

#
Hi,

I?m currently working on a header-only library that it intended to act as a ?glue" layer between an existing C++11 library (also header only) and R, by means of Rcpp.

Basically, I am trying to provide some generic templates that perform operations using the existing C++11 library and return appropriate data objects to the R environment.

My current plan for this library is that:

1. It is also c++11
2. It exists in its own namespace

Rcpp seems to have problems with the latter, but only on GCC.  I am unable to return XPtr to objects whose names are typedefs within a namespace.  However, everything works using clang++.

A reproducible example of this issue can be found at https://gist.github.com/molpopgen/989ec678664d083bf4a3 <https://gist.github.com/molpopgen/989ec678664d083bf4a3>

Version numbers are:
Rcpp - 0.11.6
R - 3.1.0
g++ - 4.9.2
clang++ ? 3.5 and 3.6
Ubuntu 14.04 LTS

I first discovered this when code I?d implemented on OS X/Yosemite/clang failed to link on my Linux box, where g++ is the default.

If you have git on your system and g++ as your default CXX, then

git clone https://gist.github.com/molpopgen/989ec678664d083bf4a3 <https://gist.github.com/molpopgen/989ec678664d083bf4a3>
cd 989ec678664d083bf4a3
##This fails on my system with GCC w/no deleter for the XPtr found, but it compiles fine if I set ~/.R/Makevars to say CXX=clang++-3.6
Rscript doit.R
##This works with any of the compilers on my Ubunutu system, because I provide a custom deleter for the XPtr
Rscript doit2.R

If you look at the comments in the C++ code in the gist, this issue arises due to a strange mix of typedefs in a namespace + a template function in the same namespace.  However, I don?t think that this is an unusual use case.  Looking at the XPtr implementation, I don?t see any reason for the symbol not to be generated.

Thanks,

Kevin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20150520/b8b704a5/attachment.html>
#
On 20 May 2015 at 15:22, Kevin Thornton wrote:
| Hi,
| 
| I?m currently working on a header-only library that it intended to act as a
| ?glue" layer between an existing C++11 library (also header only) and R, by
| means of Rcpp.
| 
| Basically, I am trying to provide some generic templates that perform
| operations using the existing C++11 library and return appropriate data objects
| to the R environment.
| 
| My current plan for this library is that:
| 
| 1. It is also c++11
| 2. It exists in its own namespace
| 
| Rcpp seems to have problems with the latter, but only on GCC.

I think I we do have a few counterexamples to that claim.

That said, it of course entirely possible that have found a bug, but I don;t
currently have time to follow links to random gists with random snippets of
code.

If there is a genuine bug we may get to a proper bug report in due course.
Or so one hopes.

Dirk
#
Dirk,

What are you asking for?  I provided a working source file + the Rscripts I used to identify the problem + ample comments about how I arrived at it.  I?m not sure how this qualifies as ?random snippets."

?Kevin
#
Kevin, 

I think Dirk is looking for a MWE (minimal working example).

Best,
--
Hao Ye
hye at ucsd.edu
#
Hmm. Thr gist looks like it might provide a MWE?




Anyway, if it looks like a possible bug you could file it at the bugreports link from description:?https://github.com/RcppCore/Rcpp/issues




-?Jaime
On Wed, May 20, 2015 at 5:51 PM, Hao Ye <hye at ucsd.edu> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20150520/9da8eccf/attachment.html>
#
I claim that I?ve provided it, so I?m assuming that the delivery (gist) is the problem.  So, here?s a copy/paste for you.  Without the custom deleter, this fails to link using GCC 4.7/4.8/4.9 with Rcpp 0.11.4 and newer.

The problem is the combination of the typedef and the function foo being a template.  Change either one of those, and all is ok (on GCC?all is fine on clang).

This example is contrived to reproduce the failure to create the XPtr?s deleter on GCC.  The original context can be seen in this diff: https://github.com/molpopgen/foRward/commit/880c0c4e4caf2e9e0b5f7263720ebcca608a6059

#include <Rcpp.h>
#include <tuple>

#ifdef USE_DELETER
namespace Rcpp {
  template<>
  inline void standard_delete_finalizer<std::tuple<int,int> >( std::tuple<int,int> * t ) { delete t; }
}
#endif

namespace foo {
  using tuple_t = std::tuple<int,int>;
  template<typename T>
  SEXP foofunc(const T & a)
  {
    return Rcpp::XPtr<tuple_t>(new tuple_t(a,a));
  }
}

SEXP foofunc_caller(const int & a) { return foo::foofunc(a); }
#
Kevin,

Still not a minimally reproducible example as it lacks

a) instructions to tell sourceCpp() to turn on C++11 (ie

   // [[Rcpp::plugins("cpp11")]]

b) build instructions

c) run instructions

We are a fairly common standard for this over here, or on SO.

Good examples are provided by the Rcpp Gallery which, when sourced by
Rcpp::sourceCpp(), also runs included R code.

If you want help from the readers of this list, help them help you by
reproducible example.  Nobody has time to figure out what you may have
meant.  Make it explicit.

Dirk
#
Dirk,

OK, I?ll try again.  I?ll respond out of order:

c)  There are no run instructions.  This issue (as stated in all of my posts on this issue) is that GCC will not load the .so from the MWE because standard_delete_finalizer is missing.  Compiling with clang++ does not have this issue, which brings us to?

a)  Again, the issue here is GCC vs clang, and [[Rcpp::plugins(?cpp11?)]] (and CXX_STD = CXX11 in a Makevars.in) have an unfortunate side-effect on all the Linux (Ubuntu) systems that I use.  They over-ride the definition of CXX in ~/.R/Makevars, which means I can only use GCC.  I?m assuming that this is an R issue, but it is important to reproducing this example, which is the raison d?etre for the R scripts in the gist?


For example, here is my ~/.R/Makevars:

cat ~/.R/Makevars
CXX=ZeppelinRules

Now, let?s see what happens with Rcpp::plugins(?cpp11?):

Rscript -e 'library(Rcpp)' -e 'sourceCpp(code="// [[Rcpp::plugins(\"cpp11\")]]\n// [[Rcpp::export]]\nvoid foo(){}",verbose=TRUE)'

The relevant output is:

g++ -std=c++11 -I/usr/share/R/include -DNDEBUG    -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp/Rtmpqaq1Pj"    -fpic  -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c file52eccfd254e.cpp -o file52eccfd254e.o
g++ -std=c++11 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_61207.so file52eccfd254e.o -L/usr/lib/R/lib -lR

So, the plugin over-rides my Makevars, and without it we learn that Zeppelin is not a C++ compiler:

Rscript -e 'library(Rcpp)' -e 'sourceCpp(code="// [[Rcpp::export]]\nvoid foo(){}",verbose=TRUE)?

The relevant output is:

ZeppelinRules -I/usr/share/R/include -DNDEBUG    -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp/Rtmpblhfp9"    -fpic  -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g  -c file530e5ce6ddd1.cpp -o file530e5ce6ddd1.o
/bin/bash: ZeppelinRules: command not found

So, my original gist was correct, because it is a MWE, and sets the cpp11 properly, in the sense that it allows me to properly select my c++ compiler via ~/.R/Makevars and avoids the side-effect described above:

Sys.setenv("PKG_CXXFLAGS" = "-std=c++11?)

Finally, here?s an all-in 1 response to:

b.) build instructions

VERSION1

This gives the following error using all combos of G++ 4.7,4.8,4.9 and Rcpp 0.11.4 through 0.11.6 on several different Linux systems (Ubuntu servers, mostly 14.04, and our HPC system which is some custom distro?):

Error in dyn.load("/tmp/RtmpoMjBFt/sourcecpp_53761e3a356a/sourceCpp_4629.so") : 
  unable to load shared object '/tmp/RtmpoMjBFt/sourcecpp_53761e3a356a/sourceCpp_4629.so':
  /tmp/RtmpoMjBFt/sourcecpp_53761e3a356a/sourceCpp_4629.so: undefined symbol: _ZN4Rcpp25standard_delete_finalizerISt5tupleIIiiEEEEvPT_
Calls: sourceCpp -> source -> withVisible -> eval -> eval -> dyn.load

(With clang++, all is cool, but you need to change your CXX yourself to see that, so edit your own ~/.R/Makevars, and don?t use Rcpp::plugins, at least on Ubuntu?)

The code is:

library(Rcpp)
Sys.setenv("PKG_CXXFLAGS" = "-std=c++11")
sourceCpp(code="#include <Rcpp.h>
#include <tuple>

#ifdef USE_DELETER
namespace Rcpp {
  template<>
  inline void standard_delete_finalizer<std::tuple<int,int> >( std::tuple<int,int> * t ) { delete t; }
}
#endif

namespace foo {
  using tuple_t = std::tuple<int,int>;
  template<typename T>
  SEXP foofunc(const T & a)
  {
    return Rcpp::XPtr<tuple_t>(new tuple_t(a,a));
  }
}

// [[Rcpp::export()]]
SEXP foofunc_caller(const int & a) { return foo::foofunc(a); }",
          verbose = TRUE)

VERSION 2:

We define USE_DELETER, and everything works with GCC:

library(Rcpp)
Sys.setenv("PKG_CXXFLAGS" = "-std=c++11 -DUSE_DELETER")
sourceCpp(code="#include <Rcpp.h>
#include <tuple>

#ifdef USE_DELETER
namespace Rcpp {
  template<>
  inline void standard_delete_finalizer<std::tuple<int,int> >( std::tuple<int,int> * t ) { delete t; }
}
#endif

namespace foo {
  using tuple_t = std::tuple<int,int>;
  template<typename T>
  SEXP foofunc(const T & a)
  {
    return Rcpp::XPtr<tuple_t>(new tuple_t(a,a));
  }
}

// [[Rcpp::export()]]
SEXP foofunc_caller(const int & a) { return foo::foofunc(a); }",
          verbose = TRUE)

The  output from gcc 4.9 on my system is:

/usr/lib/R/bin/R CMD SHLIB -o 'sourceCpp_25020.so'  'file53a24f1a73a8.cpp'  
g++ -I/usr/share/R/include -DNDEBUG    -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp/RtmphmQ6cd"   -std=c++11 -DUSE_DELETER -fpic  -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g  -c file53a24f1a73a8.cpp -o file53a24f1a73a8.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_25020.so file53a24f1a73a8.o -L/usr/lib/R/lib -lR

?Kevin