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

Dominick Samperi djsamperi at gmail.com
Tue Jan 18 23:45:50 CET 2011


This link explains very clearly why VC++ creates a temporary to initialize
the local reference, complete with a decision graph, and it seems that
the Rcpp expression template code should lead to the "create temporary"
branch: http://msdn.microsoft.com/en-us/library/szywdw8k.aspx

These comments come from an IBM site explaining when references
are directly bound when initialized (no temporary):

Direct Binding

Suppose a reference r of type T is initialized by an expression e of type U.

The reference r is bound directly to e if the following statements are true:

   - Expression e is an lvalue
   - T is the same type as U, or T is a base class of U
   - T has the same, or more, const or volatile qualifiers than U

The reference r is also bound directly to e if e can be implicitly converted
to a type such that the previous list of statements is true.
Dominick

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

> 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/56f65217/attachment.htm>


More information about the Rcpp-devel mailing list