|
From: Alf P. Steinbach on 8 May 2008 18:42 * Ben Voigt [C++ MVP]: > Alf P. Steinbach wrote: >> * Ben Voigt [C++ MVP]: >>> Alf P. Steinbach wrote: >>>> * Ben Voigt [C++ MVP]: >>>>> Alf P. Steinbach wrote: >>>>>> * Ben Voigt [C++ MVP]: >>>>>>>>> You might not see that example as typed but if( a * b = c) ... >>>>>>>>> does occure because of typing mistakes. The compiler will >>>>>>>>> catch this. >>>>>>>> And why would you want to prevent that? >>>>>>> Because the side-effect of the assignment operator is to change a >>>>>>> temporary that is immediately thrown away, obviously not >>>>>>> intended. The programmer meant to use the comparison operator == >>>>>>> instead. >>>>>> Did she? >>>>>> >>>>>> Anyway, the techniques for dealing with >>>>>> inadvertent-assignment-in-condition for built-in types (namely >>>>>> high warning level for compilation, writing constants on left >>>>>> side, code inspection, systematic testing, etc.) apply here also. >>>>> "writing constants on left side"? >>>>> >>>>> That's exactly what is going on here! >>>> Nope. An expression is not necessarily a constant, and in >>> The OP had declared the return type of his operator as const in >>> order to make such expressions const. >> Perhaps I should rephrase that for clarity then: the techniques that >> client code programmers intentionally use for dealing with... >> >> That's not what's going on above. >> >> The client code programmer who writes "if( a*b = c ) ..." is not >> intentionally writing a constant expression on the left hand side, >> because that expression could very well and would normally be >> non-constant for class type a, b and c. >> As already illustrated, the ensure-constant-lhs technique can be >> applied to the above example, and the point you reacted to was the >> statement that it can. > > No it cannot, unless you make assumptions about mathematical equalities > holding for arbitrary class types, the same ones you accused me of several > messages ago. > > At least I'm thinking of transforming that into > > if (0 == a * b - c) > > But that's not necessarily valid for all types. Some types may not even > define operator -. Sorry, but this reminds me of some old sketch where person A maintains it's impossible to walk trough a door. Person A demonstrates this by repeatedly missing the door and colliding with the wall, and after being given an example of walking through door (by person B), still A denies it's possible, and demonstrates anew how impossible it is (dang, hit the wall, again!). I already gave example of ensuring constant lhs, and in fact I already mentioned that I did, so we're two levels away from that, but again, just for variety: Rational const c = ... if( c == a*b ) ... // OK if( c = a*b ) ... // Typo, won't compile. Not that I'm promoting this convention. As I wrote elsewhere, the logic behind it is somewhat lacking, and I might add now that it also in general reduces readability. =/== is simply not worth it. >> And then the code looks different. :-) >> >> >>>> particular, in C++, an rvalue is not necessarily a constant. For >>>> class types it is in most cases not constant, e.g. the >>>> std::vector<T>().swap(v) idiom for clearing a vector v relies on >>>> this, and the rvalue non-constness is also used in the code below. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
From: Alexander Grigoriev on 8 May 2008 22:50 On the other hand, you can have operator=(T const&) const;, but only if you like weird designs... "Ben Voigt [C++ MVP]" <rbv(a)nospam.nospam> wrote in message news:u0jHCtSsIHA.484(a)TK2MSFTNGP04.phx.gbl... >>> You might not see that example as typed but if( a * b = c) ... does >>> occure because of typing mistakes. The compiler will catch this. >> >> And why would you want to prevent that? > > Because the side-effect of the assignment operator is to change a > temporary that is immediately thrown away, obviously not intended. > > The programmer meant to use the comparison operator == instead. > >
From: Ben Voigt [C++ MVP] on 9 May 2008 14:04 > I already gave example of ensuring constant lhs, and in fact I > already mentioned that I did, so we're two levels away from that, but > again, just for variety: > Rational const c = ... > if( c == a*b ) ... // OK > if( c = a*b ) ... // Typo, won't compile. You now have an extremely limited example which does not generalize well at all. How about comparing a*b to c*d? You have to make the return type of operator* const to prevent the error in a general way.
From: Alf P. Steinbach on 9 May 2008 14:25 * Ben Voigt [C++ MVP]: >> I already gave example of ensuring constant lhs, and in fact I >> already mentioned that I did, so we're two levels away from that, but >> again, just for variety: >> Rational const c = ... >> if( c == a*b ) ... // OK >> if( c = a*b ) ... // Typo, won't compile. > > You now have an extremely limited example which does not generalize well at > all. Yes, that's correct. I think I've already said enough about the const lhs technique so I shall not elaborate on its many failings. > How about comparing a*b to c*d? What about it? Is the question how to apply const lhs technique to that case? Not that I recommend it, but it would go like this: Rational const ab = a*b; Rational const cd = c*d; if( ab == cd ) ... > You have to make the return type of > operator* const to prevent the error in a general way. As already shown else-thread, no, writing = for == can be detected at compile time in other ways, the most effective and (IMHO) least ugly to make '=' for assignment invalid. That it's possible does not mean it's a good idea, because the problem it means to avoid is insignificant and will be detected anyway if it occurs, and the solution has associated costs, namely non-conventional notation, reducing readability and clarity. Just as it isn't a good idea, in general, to make rvalues const, because the problem is insignificant and will be detected anyway, e.g. through testing or via compiler warnings, and the solution has associated costs, in particular prohibiting an important possible optimization. Cheers, & hth., - Alf -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail?
From: Ben Voigt [C++ MVP] on 9 May 2008 16:43
> As already shown else-thread, no, writing = for == can be detected at > compile time in other ways, the most effective and (IMHO) least ugly > to make '=' for assignment invalid. That it's possible does not mean > it's a good idea, because the problem it means to avoid is > insignificant and will be detected anyway if it occurs, and the > solution has associated costs, namely non-conventional notation, > reducing readability and clarity. Just as it isn't a good idea, in > general, to make rvalues const, because the problem is insignificant > and will be detected anyway, e.g. through testing or via compiler > warnings, and the solution has associated costs, in particular > prohibiting an important possible optimization. I'm still going to trust Scott Meyers on this one, especially because he recommends the const r-values *in a discussion on RVO*: http://groups.google.com/group/comp.lang.c++.moderated/msg/e60d78d50da3f841 > > > Cheers, & hth., > > - Alf |