From: Vladimir Grigoriev on
In my opinion it is a bug indeed because using explicitly the member
operator resolves the problem.

size_type _Off = size() == 0 ? 0 : _Where.operator -( begin() );

Vladimir Grigoriev

"Igor Tandetnik" <itandetnik(a)mvps.org> wrote in message
news:OijleXlfKHA.5784(a)TK2MSFTNGP05.phx.gbl...
Vladimir Grigoriev wrote:
> No, you are mistaken! The problem is in Microsoft VC++ code. It breaks the
> main principle of OOP that a server code should not depend on a client
> code.

This principle cannot be readily applied to STL - all it does is manipulate
user-provided classes and naturally depends on their behavior. However, the
implementation should avoid _unintended_ points of customization.
Unfortunately, C++ makes it difficult to do so.

For discussion of a similar set of issues, see

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1387.htm

These defect reports attempt to plug a particular hole - that of picking up
unintended user-defined functions by Koenig lookup. Your case doesn't
involve Koenig lookup, so it's different in the letter though similar in
spirit. It's not clear to me whether VC2005's implementation is outright
non-conforming, but from a quality-of-implementation standpoint it could
certainly be improved (which, apparently, it was in later versions).

Having said that, defining a generally-applicable templated overloaded
operator in global scope is probably not the best idea. It's too easy to
pick it up by accident.
--
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


From: Igor Tandetnik on
Vladimir Grigoriev wrote:
> In my opinion it is a bug indeed because using explicitly the member
> operator resolves the problem.

I don't quite understand this reasoning. The definition of "bug" is not "there exists an alternative way of performing the same task that I like better", it's "the current way of performing the task violates the specification". You can't say: it's a bug _because_ I know how to fix it. You should say: it's a bug because it violates requirement X, and luckily I happen to know how to fix it.

And I can't find anything in the specification (the C++ standard) that would explicitly prohibit the current implementation. Which, arguably, is a defect in the standard itself. In fact, a similar problem was recognized as a defect and the wording clarified accordingly, but it appears that the fix is too narrow.
--
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
From: Vladimir Grigoriev on
I am naming it as a bug becase the designer thought one thing but had done
another thing. He meant using of a concrete member operator however had
written the expression in general form given the freedom in interpretation
of the expression.

In fact the expression

size_type _Off = size() == 0 ? 0 : _Where -begin();

is not fully defined because there is not in the class definition of _Myt
such operator as

difference_type operator-(const _Myt& _Right) const
{ // return difference of iterators
return (*(_Mybase *)this - _Right);
}

There is an operator

difference_type operator-(const _Mybase& _Right) const
{ // return difference of iterators
return (*(_Mybase *)this - _Right);
}

where _Mybase is a base class for _Myt..

It is a bug because the designer should either include the operator

difference_type operator-(const _Myt& _Right) const
{ // return difference of iterators
return (*(_Mybase *)this - _Right);
}
along with the original operator there Mybase& is used, or use the form of
specifying the member operator explicitly in the expression.

Vladimir Grigoriev




Vladimir Grigoriev

"Igor Tandetnik" <itandetnik(a)mvps.org> wrote in message
news:uT$jGklfKHA.5036(a)TK2MSFTNGP04.phx.gbl...
Vladimir Grigoriev wrote:
> In my opinion it is a bug indeed because using explicitly the member
> operator resolves the problem.

I don't quite understand this reasoning. The definition of "bug" is not
"there exists an alternative way of performing the same task that I like
better", it's "the current way of performing the task violates the
specification". You can't say: it's a bug _because_ I know how to fix it.
You should say: it's a bug because it violates requirement X, and luckily I
happen to know how to fix it.

And I can't find anything in the specification (the C++ standard) that would
explicitly prohibit the current implementation. Which, arguably, is a defect
in the standard itself. In fact, a similar problem was recognized as a
defect and the wording clarified accordingly, but it appears that the fix is
too narrow.
--
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


From: Igor Tandetnik on
Vladimir Grigoriev wrote:
> I.e. I wanted to say that when an operator of a derived class uses a
> reference to a base class as a parameter it leaves a hole in the opration
> implementation. In fact this means that the designer is saying: "I am not
> responsible if you will use a reference to the deribed class as an parameter
> of the operator. In this case you may use any ypur own implementation of the
> operator."

Yes, that's an example of an unintended point of customization. For discussion, see

http://www.ddj.com/cpp/184401876
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1691.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1296.asc

--
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
From: Igor Tandetnik on
Vladimir Grigoriev wrote:
> It is a bug because the designer should either include the operator
>
> difference_type operator-(const _Myt& _Right) const
> { // return difference of iterators
> return (*(_Mybase *)this - _Right);
> }
> along with the original operator there Mybase& is used, or use the form of
> specifying the member operator explicitly in the expression.

Again, you are saying: it's a bug _because_ the implementation should be written differently. This confuses cause and effect: "the wind is blowing because trees are shaking." The causality should go the other way round: the implementation should be written differently _because_ the current implementation has a bug. This of course still requires one to demonstrate that the current implementation does in fact have a bug, and not just a behavior that you might not like but that is nevertheless conforming.
--
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