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

Dominick Samperi djsamperi at gmail.com
Tue Jan 18 22:46:32 CET 2011


Opps, I was too quick to declare victory here. That warning about
temporary reference initialization is not innocuous: crashes still
occur under VC++ (even with the updated RcppCommon.h) but
it is difficult to predict when they will occur. The Extractor.h
work-around fixes the problem for now.

The question that remains unanswered is: is this a quirk of
VC++ or is the warning something that applies more generally?

Dominick

On Tue, Jan 18, 2011 at 4:18 PM, Dominick Samperi <djsamperi at gmail.com>wrote:

> To finish up this thread, it turns out that the VC++ problems did
> help to reveal an architecture-dependent behavior of Rprintf
> (under GCC) that
> developers probably should be aware of, and it also points to
> a potential problem with the way temporary references are
> initialized in the expression template code.
>
> On the other hand, the non-Rprintf related problems seem to
> be due to the fact that I did not update RcppCommon.h in
> my VC++ builds. After updating RcppCommon.h (and adding
> VC++ to the list of supported compilers), the expression
> template code works fine. I still get the warnings about the
> initialization of reference temporaries though.
>
> On Rprintf, it is safest to not use format controls like
> "%lf" and "%Lf". Use "%f" instead. Since I have programmed
> in C/C++ for a long time I was in the habit of using "%lf",
> but the "l" qualifier has since been redefined to apply to
> ints (and long ints) only, and "%Lf" is intended for use
> with 'long double' type.
>
> Dominick
>
>
> On Sun, Jan 16, 2011 at 3:34 PM, Dominick Samperi <djsamperi at gmail.com>wrote:
>
>> 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/20110118/182ab2ef/attachment-0001.htm>


More information about the Rcpp-devel mailing list