[Rcpp-devel] sugar under Wingows/g++ (MinGW) odd behavior.

Dominick Samperi djsamperi at gmail.com
Sun Jan 16 21:34:04 CET 2011


It appears that this is a matter of compiler interpretation of the C++
standards,
and it is not easy to see which compiler is correct (g++ or VC++).

When I disable the VC++ work-around I get the following warning from this
compiler about the Plus_Vector_Vector constructor:

c:\w\dev\stats\rbuild\Rcpp\inst\include\Rcpp/sugar/operators/plus.h(39):
warning C4413:
'Rcpp::sugar::Plus_Vector_Vector<RTYPE,LHS_NA,LHS_T,RHS_NA,RHS_T>::lhs' :
reference member is initialized to a temporary that doesn't persist after
the constructor exits

Obviously this is perfectly consistent with the kind of problem I reported
earlier in
this thread. What is not obvious is why the reference is initialized to
a temporary.

I tried reproducing the problem (using VC++) with a simpler example taken
from
the Wiki page on expression templates. I simply added a get_ref() method
and used this in the VecDifference constructor initialization. There were no
warnings and the program ran without problems, so the reason for the
warning in the case of Rcpp expression templates is not clear.

The C++0x standard includes some changes in the way references are
handled. I don't know if this is relevant.

Dominick

On Sat, Jan 15, 2011 at 10:55 PM, Dominick Samperi <djsamperi at gmail.com>wrote:

> Romain,
>
> I found a work-around for the VC++ problem. All I have to do
> is make sure the code that is currently ifdef-ed in Extractor.h
> is NOT enabled under VC++ (when _MSC_VER is defined).
> Currently this code is conditionally compiled with
> #ifndef IF_GCC_450_OR_LATER, so the additional condition
> that _MSC_VER is NOT defined must be added, and only
> the identity class at the top of Extractor.h is used.
>
> A comment in this file suggests that you have already
> observed problems under windows with Rcpp::Fast
> vector extraction, presumably with MinGW/g++. The
> comment goes on to say that it may be a g++ 4.5
> issue and not a Windows issue. Obviously this thread
> has shown that this is not the complete story.
>
> I do not know why VC++ has a problem with
> Rcpp::Fast vector extraction. With all of the pointer
> manipulation it may have something to do with
> incompatible word sizes, memory alignment,
> or related low-level issues.
>
> Thanks,
> Dominick
>
>
> On Sat, Jan 15, 2011 at 2:27 PM, Dominick Samperi <djsamperi at gmail.com>wrote:
>
>> So that there is no confusion, I should add that the problems that I
>> report
>> here do not occur under Linux/g++ or under MinGW/g++ (the supported
>> environments), where Rcpp/sugar seems to work fine.
>>
>>
>> On Sat, Jan 15, 2011 at 1:23 PM, Dominick Samperi <djsamperi at gmail.com>wrote:
>>
>>>
>>>
>>> On Sat, Jan 15, 2011 at 4:15 AM, Romain Francois <
>>> romain at r-enthusiasts.com> wrote:
>>>
>>>> Le 13/01/11 16:29, Dominick Samperi a écrit :
>>>>
>>>>  The template expression code is very interesting, but it
>>>>> does not work as expected under
>>>>> Windows/g++/MinGW/32bit/Rterm.exe. The problem
>>>>> does not appear when I use Rgui.exe, or if I use
>>>>> 64bit Windows!
>>>>>
>>>>> Consider the following C++ code called using
>>>>> .Call('testsugar',1:5,1:5):
>>>>>
>>>>> RcppExport SEXP testsugar(SEXP x_, SEXP y_) {
>>>>>     Rcpp::NumericVector x(x_), y(y_);
>>>>>     Rprintf("%d, %lf, %lf\n", (x+y).size(), (x+y)[0], (x+y)[1]);
>>>>>     return R_NilValue;
>>>>> }
>>>>>
>>>>> Under Linux/GCC, or 64bit Windows/g++, or
>>>>> 32bit Windows/g++ I get the expected result:
>>>>>
>>>>> 5, 2.0, 4.0
>>>>>
>>>>> Under Windows/32bit/Rterm.exe I get:
>>>>>
>>>>> 5, 0.0, 0.0
>>>>>
>>>>
>>>> Intriguing. Maybe Rprintf is to blame. Can you try this instead:
>>>
>>>
>>>>
>>>> RcppExport SEXP testsugar(SEXP x_, SEXP y_) {
>>>>    Rcpp::NumericVector x(x_), y(y_);
>>>>        int n = (x+y).size() ;
>>>>        double xy0 = (x+y)[0] ;
>>>>        double xy1 = (x+y)[1] ;
>>>>    Rprintf("%d, %lf, %lf\n", n, xy0, xy1);
>>>>    return R_NilValue;
>>>>
>>>> }
>>>>
>>>
>>>  Good guess, I found a problem with Rprintf yesterday, but this
>>> will not fix it. The problem is not caused by the arbitrary evaluation
>>> order of the arguments to Rprintf. It is caused by the different
>>> behavior of the format control "%lf" under different architectures!
>>> In particular, the problem goes away under i386/32bit Windows using
>>> MinGW/g++ when "%lf" is replaced with "%f". I could not find this
>>> documented anywhere.
>>>
>>> Of course, this has nothing to do with Rcpp, and it might
>>> be of interest to r-devel.
>>>
>>> For me this was just a distraction because the problem with
>>> Visual C++ is still alive and well and has nothing to do with
>>> Rprintf. As this information might be helpful in other
>>> (non-VC++) contexts here is what I am seeing.
>>>
>>> Consider:
>>>
>>>
>>> RcppExport SEXP testsugar(SEXP x_, SEXP y_) {
>>>     Rcpp::NumericVector x(x_), y(y_);
>>>     Rprintf("val = %f\n", (x+y)[0]);
>>>     return R_NilValue;
>>> }
>>>
>>> This goes through operator+(lhs,rhs) in plus.h, which triggers the
>>> construction of an object of type Plus_Vector_Vector, and the
>>> construction seems to happen without problems, because the
>>> following Rprint's print what you would expect in the
>>> constructor:
>>>
>>> Rprintf("RTYPE = %d\n", RTYPE); // get 14, REALSXP
>>> Rprintf("size: %d, %d, %d\n", lhs.size(), rhs.size(), this->size()); //
>>> 5, 5, 5
>>> Rprintf("vals: %f, %f, %f, %f\n", lhs[0], rhs[0], lhs[1], rhs[1]); //
>>> 1.0, 1.0, 2.0, 2.0
>>> Rprintf("ptrs: %p, %p\n", &lhs, &rhs); // reasonable addresses
>>>
>>> But when you leave the constructor the two objects lhs and rhs get
>>> clobbered, even though their respective addresses seem not to
>>> change. In particular, the following print statements when inserted
>>> into operator[](int i) show garbage (and sometimes cause a crash):
>>>
>>> Rprintf("ptrs: %p, %p\n", &lhs, &rhs); // this is OK, same addresses as
>>> above
>>> Rprintf("lhs_ = %f\n", lhs_); // 0.0 or garbage
>>> Rprintf("rhs_ = %f\n", rhs_); // 0.0 or garbage
>>> Rprintf("size = %d\n", lhs.size()); // usually crashes.
>>>
>>> Dominick
>>>
>>>
>>>>  (Under VC++ there are more serious problems including
>>>>> corruption of other in the wrap-up function
>>>>> Vector(VectorBase& other), but since VC++ is not
>>>>> supported I will not elaborate here.)
>>>>>
>>>>> Thanks,
>>>>> Dominick
>>>>>
>>>>
>>>>
>>>> --
>>>> Romain Francois
>>>> Professional R Enthusiast
>>>> +33(0) 6 28 91 30 30
>>>> http://romainfrancois.blog.free.fr
>>>> |- http://bit.ly/fT2rZM : highlight 0.2-5
>>>> |- http://bit.ly/gpCSpH : Evolution of Rcpp code size
>>>> `- http://bit.ly/hovakS : RcppGSL initial release
>>>>
>>>>
>>>> _______________________________________________
>>>> Rcpp-devel mailing list
>>>> Rcpp-devel at lists.r-forge.r-project.org
>>>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20110116/12ab70e3/attachment.htm>


More information about the Rcpp-devel mailing list