From: Vladimir Grigoriev on
When I use std::less_equal predicate with the std::min() algorithm (tu
change the order of returned elements in case they are equal) the Visual C++
2005 EE abort my program in the internal function

bool __CLRCALL_OR_CDECL _Debug_lt_pred()

reporting the following



_DEBUG_ERROR2("invalid operator<", _Where, _Line);

Is it correct behaviour of the compiler? Does the Standard forbid to use
std::less_equal with std::min?



Vladimir Grigoriev:




From: Vladimir Grigoriev on

"Igor Tandetnik" <itandetnik(a)mvps.org> wrote in message
news:uZER%23BwkKHA.5608(a)TK2MSFTNGP05.phx.gbl...

Ok, now imagine an official language in the standard that would capture this
behavior:

min(a, b, comp): returns the smaller of a and b as defined by comp. If a and
b are "equal" (that is, !comp(a, b) && !comp(b, a)), then returns a if comp
is a less-than type of predicate, but b if it's less-than-or-equal type of
predicate. Insert the formal definition of the two types here.


I have imagined that! But I have formulated this another way. If a binary
predicate has value of true then 'b' is returned. Otherwise 'a' is
returned. So I do not see a problem. Moreover including std::less_equal into
std::min makes code readable and clear.

std::min( a, b, std::less_equal<T>() );

It is funny to note that the compiler allows to use std::greater instead of
std::less in the std::min in spite of that this looks strange.
Moreover I can show another example when applying std::less_equal is useful.
For example you want to find the last minimum element in a sequence. Then
you could use std::less_equal instead of std::less.

int a[] = { 6, 1, 7, 1, 8 };


int *p = std::min_element( a, a + sizeof( a ) / sizeof( *a ),

std::less_equal() );


In fact without any serious reason the Microsoft compiler prevents from
compiling of a valid code. In my opinion it is one mode serious bug of the
Microsoft compiler. I have not seen any reasonable explanation why this code
may not be compiled. It seems that Microsoft inserted this check everywhere
in its library without any thought about consequences

Vladimir Grigoriev.


From: Ulrich Eckhardt on
Vladimir Grigoriev wrote:
> But I have formulated this another way. If a binary
> predicate has value of true then 'b' is returned. Otherwise 'a' is
> returned. So I do not see a problem. Moreover including std::less_equal
> into std::min makes code readable and clear.
>
> std::min( a, b, std::less_equal<T>() );
>
> It is funny to note that the compiler allows to use std::greater instead
> of std::less in the std::min in spite of that this looks strange.

Yes, strange indeed. However, it only gives you the first element according
to the given order. Using less in ascending order, otherwise descending
order.

> Moreover I can show another example when applying std::less_equal is
> useful. For example you want to find the last minimum element in a
> sequence. Then you could use std::less_equal instead of std::less.
>
> int a[] = { 6, 1, 7, 1, 8 };
>
>
> int *p = std::min_element( a, a + sizeof( a ) / sizeof( *a ),
>
> std::less_equal() );

Use a reverse iterator to search from the end. All search functions return
the first match, not the last.

> In fact without any serious reason the Microsoft compiler prevents from
> compiling of a valid code. In my opinion it is one mode serious bug of the
> Microsoft compiler. I have not seen any reasonable explanation why this
> code may not be compiled.

Look again, someone mentioned the C++ standard. ;)

> It seems that Microsoft inserted this check
> everywhere in its library without any thought about consequences

Nope, the strict ordering comes from the C++ standard which in turn took it
from the STL. You're barking up the wrong tree. BTW: I'd ask this on
comp.lang.c++.moderated, you have typically more C++ experts there.

Uli

--
C++ FAQ: http://parashift.com/c++-faq-lite

Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932
From: Vladimir Grigoriev on

"Ulrich Eckhardt" <eckhardt(a)satorlaser.com> wrote in message
news:p09u17-k7e.ln1(a)satorlaser.homedns.org...
> Vladimir Grigoriev wrote:
>> But I have formulated this another way. If a binary
>> predicate has value of true then 'b' is returned. Otherwise 'a' is
>> returned. So I do not see a problem. Moreover including std::less_equal
>> into std::min makes code readable and clear.
>>
>> std::min( a, b, std::less_equal<T>() );
>>
>> It is funny to note that the compiler allows to use std::greater instead
>> of std::less in the std::min in spite of that this looks strange.
>
> Yes, strange indeed. However, it only gives you the first element
> according
> to the given order. Using less in ascending order, otherwise descending
> order.

Yes, using std::greater reverse std::min to std::max and std::max to
std::min. It is funny but it is an interesting possibility. However using
std::less_equal looks more natural with using std::min than using for
example std::greater with std::min.

>
>> Moreover I can show another example when applying std::less_equal is
>> useful. For example you want to find the last minimum element in a
>> sequence. Then you could use std::less_equal instead of std::less.
>>
>> int a[] = { 6, 1, 7, 1, 8 };
>>
>>
>> int *p = std::min_element( a, a + sizeof( a ) / sizeof( *a ),
>>
>> std::less_equal() );
>
> Use a reverse iterator to search from the end. All search functions return
> the first match, not the last.
>

How to use reverse iterators with arrays?

>> In fact without any serious reason the Microsoft compiler prevents from
>> compiling of a valid code. In my opinion it is one mode serious bug of
>> the
>> Microsoft compiler. I have not seen any reasonable explanation why this
>> code may not be compiled.
>
> Look again, someone mentioned the C++ standard. ;)
>
>> It seems that Microsoft inserted this check
>> everywhere in its library without any thought about consequences
>
> Nope, the strict ordering comes from the C++ standard which in turn took
> it
> from the STL. You're barking up the wrong tree. BTW: I'd ask this on
> comp.lang.c++.moderated, you have typically more C++ experts there.

Yes, I do not know the standard but I think that strict ordering requirments
is applied not to all algorithms. Otherwise the existence of std::less_equal
and std::greater_equal in C++ have no any greate sense.

Vladimir Grigoriev


From: Igor Tandetnik on
Vladimir Grigoriev wrote:
> In fact without any serious reason the Microsoft compiler prevents from
> compiling of a valid code.

Yours is not a valid code, it exhibits undefined behavior. The C++ standard requires that the predicate be a strict weak ordering, and less_equal isn't.

> In my opinion it is one mode serious bug of the
> Microsoft compiler.

It's not a bug, it's a feature.

> I have not seen any reasonable explanation why this code
> may not be compiled.

To be precise, it compiled - it failed at run time. Anyway, MSVC's STL implementation is doing you a favor by turning an instance of undefined behavior into a hard error, so you can find and fix your bug more easily.

> It seems that Microsoft inserted this check everywhere
> in its library without any thought about consequences

No - it inserted this check _because_ it thought about consequences.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925