0

std::stringstream は Rcpp では動作しないようです。問題を切り分けるために、最小限のプログラムを作成しました。

#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文字列を float に変換するだけです。はRf_PrintValueデバッグ用です。OSX 10.16.7 の R では、

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

別のマシン (Ubuntu) では、期待どおりに動作します。

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

OSX で小さな通常の C++ プログラムを試してみましたが、もちろん stringstream を使用して文字列と浮動小数点数を変換しても問題なく動作します。

OSX で使用されるコンパイラは MacPorts g++-mp-4.4 です。

更新: _GLIBCXX_DEBUG が有効な場合、stringstream と Stringstream の OSX が double で動作しないという以前に提起された問題を発見しました。ただし、/usr/bin/g++-4.2 でデフォルトの gcc-4.2 を使用してその問題でテスト プログラムをコンパイルすると、エラーが発生しますが、/opt/local/bin/g++-mp-4.4 でコンパイルすると正常に動作します。

ただし、Rcpp コードを次のようにコンパイルしました。

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

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

したがって、これが同じ問題かどうかはわかりません。

更新 2: https://discussions.apple.com/thread/2166586?threadID=2166586&tstart=0で の議論に従って、コードの先頭に以下を追加しました。

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

また、@Kerrekの提案に従って初期化ffloat f=0;れます(ただし、これは何も変更しないはずです)。stof

Mac での出力は同じです。

4

2 に答える 2

1

RまたはRCPPはわかりませんが、次のコードが未定義の動作をトリガーするに違いありません。

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

使用する前に初期化 することはなく、初期f化されていない変数の読み取りはUBです。float f = 0;安全になりたいと言ってください。

于 2011-12-12T19:46:58.067 に答える
1

これは、通常の Xcode に同梱されているコンパイラ スイートを使用する Lion で問題なく動作します。

> 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

あなたの R も gcc 4.4 でコンパイルされましたか?

于 2011-12-14T12:15:36.683 に答える