[cfe-dev] [libc++] possible bug?

Howard Hinnant hhinnant at apple.com
Mon Apr 23 17:09:41 PDT 2012


On Apr 23, 2012, at 1:39 PM, Ovanes Markaryan wrote:

> Sorry, don't know why this email went directly to Matthieu instead of the list...
> 
> ---------- Forwarded message ----------
> From: Ovanes Markaryan <om_clang at keywallet.com>
> Date: Mon, Apr 23, 2012 at 10:30 PM
> Subject: Re: [cfe-dev] [libc++] possible bug?
> To: Matthieu Monrocq <matthieu.monrocq at gmail.com>
> 
> 
> Hello Matthieu,
> 
> please see my answers below.
> 
> On Mon, Apr 23, 2012 at 6:53 PM, Matthieu Monrocq <matthieu.monrocq at gmail.com> wrote:
> 
> 
> Le 22 avril 2012 23:58, Ovanes Markaryan <om_clang at keywallet.com> a écrit :
> 
> 
> On Sun, Apr 22, 2012 at 11:32 PM, Marc Glisse <marc.glisse at inria.fr> wrote:
> On Sun, 22 Apr 2012, Ovanes Markaryan wrote:
> 
> Hello *,
> just tried to compile SYMPHONY-5.4.4 with clang 3.0 + libc++ (tag 31). While
> compiling it I receive this error:
> 
> include/c++/v1/algorithm:643:97: error: invalid operands to binary
> expression
>       ('const reducedCost' and 'const reducedCost')
>     _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1&
> __y) const {return __x < __y;}
> 
> [...]
> 
> 
>     bool operator<(const reducedCost & other)
> 
> Missing const here. It is often preferable to avoid making operators member functions when you can avoid it.
> 
>     {
>         return (value>other.value);
>     }
> 
> -- 
> Marc Glisse
> 
> Hello Marc,
> 
> you are definitely right. I overlooked it, since as already wrote this is not my code (just copy pasted it from the lib)... But in my tests I commented out this operator< and provided the specialization of  std::less, to just test it and it failed as well. I did not test with both enable (operator< and less-specialization). Actually this code is somehow really bad, because less is actually not less but greater ;) This code compiles fine with gcc and clang + gcc's version of stdlib. As far as I remember the standard requires that std::less is specialized to allow the less comparison or the operator< is implicitly used through the generalized less. In my tests less specialization was not considered by make_heap. This is my point.
> 
> 
> Two questions:
> 
> 1. Does it work if you actually specify that `operator<` is `const` ?
>  yes.
> 
> 2. Did you were careful about putting the specialization of `less` (for this class) before its first use ? (it is not clear from your example)
> Yes. Please the attached file. 
> 
> If you could, for example, provide a simple attachment that reproduces the issue it would be slightly simpler to investigate.
> 
> Here we go:
> 
> #include <algorithm>
> #include <iterator>
> #include <functional>
> 
> struct reducedCost
> {
>     /** To avoid computing two times the same row direction will have strange
>      values, direction is -1 or 1 if for only one of the two direction
>      rc is <0 and is -2 or 2 if the two direction have one <0 rc with the sign
>      indicating which one of the two directions is the best.<br>
>      Note that by theory only one reduced cost (for u_i, or v_i)
>      maybe negative for each direction.
>      */
>     int direction;
>     /** gammSign is the sign of gamma (corresponding to taking rc for u_i or v_i)
>      for the best of the two rc for this row.*/
>     int gammaSign;
>     /** gammaSign2 is the sign of gamma for the worst of the two rc for this row.*/
>     int gammaSign2;
>     /** if both reduced costs are <0 value is the smallest of the two.*/
>     double value;
>     /** greatest of the two reduced costs */
>     double value2;
>     /** index of the row.*/
>     int row;
> #ifdef TEST_WITH_OPLESS_CONST
>     bool operator<(const reducedCost & other)const
>     {
>         return (value>other.value);
>     }
> #endif
> };
> 
> #ifdef TEST_WITH_LESS_SPEC
> namespace std
> {
>     template<>
>     struct less<reducedCost>
>         : ::std::binary_function<reducedCost, reducedCost, bool>
>     {
>         bool operator()(const reducedCost & lhs, const reducedCost & rhs)const
>         {
>             return lhs.value>rhs.value;
>         }
>     };
> }
> #endif
> 
> int main()
> {
>   reducedCost r[100]={};
> 
>   std::make_heap(&r[0], &r[0]+100);
>   return 0;
> };
> 
>  
> I compiled it with clang 3.0 and libc++ taged with release_31. Here the both command lines:
> This will fail
> $ ~/toolsets/clang-3.0/bin/clang++ -DTEST_WITH_LESS_SPEC=1 -stdlib=libc++ -I/home/ovanes/toolsets/clang-3.0/include/c++/v1  -L/home/ovanes/toolsets/clang-3.0/lib make_heap_test.cpp
> This works:
> $ ~/toolsets/clang-3.0/bin/clang++ -DTEST_WITH_OPLESS_CONST=1 -stdlib=libc++ -I/home/ovanes/toolsets/clang-3.0/include/c++/v1  -L/home/ovanes/toolsets/clang-3.0/lib make_heap_test.cpp

The make_heap function overload that does not take a comparator is specified to use operator<, not less<T>, in 25.4 [alg.sorting]/p1.

Howard





More information about the cfe-dev mailing list