0

It seems std::stringstream doesn't work with Rcpp. To isolate the problem, I wrote a minimal program:

#include <string>
#include <sstream>
#include <Rcpp.h>

float atof(std::string a) {
        std::stringstream ss(a);
        Rf_PrintValue(Rcpp::wrap(a));
        float f;
        Rf_PrintValue(Rcpp::wrap(f));
        ss >> f;
        Rf_PrintValue(Rcpp::wrap(f));
        return (f);
}

RcppExport SEXP tsmall(SEXP sR) {
        std::string sC = Rcpp::as<std::string>(sR);
        return Rcpp::wrap(atof(sC));
}

tsmall should just convert a string to float. The Rf_PrintValue is for debugging. Now in R on a OSX 10.16.7, I get

> dyn.load("min.so")
> a = .Call("tsmall","0.213245")
[1] "0.213245"
[1] 0
[1] 0
> a
[1] 0

On another machine (Ubuntu), it works as expected:

> dyn.load("min.so")
> a = .Call("tsmall","0.213245")
[1] "0.213245"
[1] 1.401298e-45
[1] 0.213245
> a
[1] 0.213245

I tried a small normal C++ program on the OSX, and of course it works fine to use stringstream to convert string and floats.

The compiler used on OSX is MacPorts g++-mp-4.4.

Update: I found an issue raised earlier about stringstream and OSX at Stringstream not working with doubles when _GLIBCXX_DEBUG enabled. However, when I compile the test program in that issue with the default gcc-4.2 in /usr/bin/g++-4.2 I get the error, but compiling with /opt/local/bin/g++-mp-4.4 works fine.

However, I had compiled the Rcpp code as

$ PKG_CPPFLAGS=`Rscript -e 'Rcpp:::CxxFlags()'` \
         PKG_LIBS=`Rscript -e 'Rcpp:::LdFlags()'` \
         R CMD SHLIB min.cpp

which used gcc-4.4:

/opt/local/bin/g++-mp-4.4 -I/opt/local/lib/R/include -I/opt/local/lib/R/include/x86_64 -I/opt/local/lib/R/library/Rcpp/include -I/opt/local/include    -fPIC  -pipe -O2 -m64 -c min.cpp -o min.o
/opt/local/bin/g++-mp-4.4 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/opt/local/lib -o min.so min.o /opt/local/lib/R/library/Rcpp/lib/x86_64/libRcpp.a -L/opt/local/lib/R/lib/x86_64 -lR

so I am not sure if this is the same issue.

Update 2: Following the discussion at https://discussions.apple.com/thread/2166586?threadID=2166586&tstart=0, I added the following to the top of my code:

#ifdef GLIBCXXDEBUG
#define GLIBCXX_DEBUGDEFINED "1"
#else
#define GLIBCXX_DEBUGDEFINED "<undefined>"
#endif

and also initialized f as float f=0; in stof according to @Kerrek's suggestion (although this should not change anything).

The output on the Mac is still the same.

Community
  • 1
  • 1
highBandWidth
  • 16,751
  • 20
  • 84
  • 131

2 Answers2

1

I don't know R or RCPP, but I bet the following code triggers undefined behaviour:

    float f;
    Rf_PrintValue(Rcpp::wrap(f));

You are never initializing f before using it, and reading an uninitialized variable is UB. Say something like float f = 0; to be safe.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I did that to see where the returned value is coming from. I can change it to an initialized float value as `float f=0;` and the output remains the same. – highBandWidth Dec 12 '11 at 19:56
1

This works just fine for me on Lion with the regular Xcode shipped suite of compilers.

> require(inline)
Le chargement a nécessité le package : inline
> require(Rcpp)
Le chargement a nécessité le package : Rcpp
Le chargement a nécessité le package : int64
> 
> inc <- '
+ float atof(std::string a) {
+         std::stringstream ss(a);
+         Rf_PrintValue(Rcpp::wrap(a));
+         float f = 0. ;
+         Rf_PrintValue(Rcpp::wrap(f));
+         ss >> f;
+         Rf_PrintValue(Rcpp::wrap(f));
+         return (f);
+ }
+ '
> 
> fx <- cxxfunction( signature( sR = "character" ), '
+     std::string sC = as<std::string>(sR);
+     return wrap(atof(sC));
+ ', plugin = "Rcpp", includes = inc )
> fx( "1.2" )
[1] "1.2"
[1] 0
[1] 1.2
[1] 1.2

Was your R compiled with gcc 4.4 as well ?

Romain Francois
  • 17,432
  • 3
  • 51
  • 77
  • Thanks! This code also just returns 0. I am not sure about the R compilation. I simply installed it with MacPorts, and I am not sure if Macports used the XCode gcc or the gcc it installed. I could build another R and test it either way if it is going to help. Although I think the possible issue I referenced with 10.6 was fixed in 10.7 (Lion), so it might not show in your system. – highBandWidth Dec 14 '11 at 15:27
  • I downloaded the prebuilt stable binary from http://cran.r-project.org/bin/macosx/ and it worked fine with it. The problem I guess is only with the Macports R because it probably uses the bad gcc of 10.6. – highBandWidth Dec 15 '11 at 20:20
  • perhaps. usually, I try to stay out of trouble by just using the compilers, etc ... shipped by XCode – Romain Francois Dec 16 '11 at 14:37