Prev: Unicode question
Next: warning C4251: 'CObj1::m_Obj2 : class 'CObj2' needs to have dll-interface to be used by clients of class 'CObj1'
From: Vladimir Grigoriev on 16 Dec 2009 08:50 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 16 Dec 2009 09:06 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 16 Dec 2009 09:24 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 16 Dec 2009 09:29 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 16 Dec 2009 09:48
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 |