Re: Order of evaluation of function arguments
Carlos Moreno wrote:
Maciej Sobczak wrote:
James Kanze wrote:
(Implicite conversions, on the other hand, are objectively bad,
and if the coding standard didn't forbid them, I'd fight to get
it changed.)
Is it a universal rule? What about this:
while (stream >> x)
{
// ...
}
I would say that implicit conversions between fundamental
types is what is broken in C++ (this is what we get from C),
but the concept itself is not necessary stupid and can be
used with advantage for user-defined types.
Just o play the devil's advocate a bit (that's always fun, you
have to admit it! :-))...
You too:-). (It's one of my favorite games.)
I don't think prohibiting (as in, absolutely banning) implicit
conversions would hurt any more than it would help --- including
the above; if we ban implicit conversions for built-ins, I'd
probably rather the consistency of also banning them for UDTs
(the mess of UDTs behave like this whereas built-ins behave
like that is already messy enough, don't you think?).
If there were no implicit conversion, I think we could easily
live with something like:
while (succeeded (stream >> x))
Not really. I don't like the implicit conversion in the
original, but it is a well known and well understood one, so the
effect on readability is minimal. On the other hand, a while
statement controls program flow; it should never affect program
state (on the grounds that one statement should do one, and only
one thing).
Or, for the OO extreme fans ;-) while ((stream >> x).ok()),
though this one really looks ugly --- the above, well, not so
much.
If I the implicit conversion was the only thing I didn't accept,
I'd write:
while ( ! (stream >> x).failed() )
But this form points out the real problem very well---the
statement does two, unrelated things: it inputs a value, and it
controls flow.
In this particular case:
-- The functions for reading the state of an ios are so
confused and misnamed, it's probably better to avoid them,
and use the implicit conversion (which is based on the only
useful function). It's not good, since it doesn't say what
you are really testing, but the others are worse, since
given their names, they lie about what you are really
testing. (Better to say nothing than to lie. And for the
reader better to know you don't know, than to think you
know, and be wrong.)
-- The embedded modification and test has become so ubiquous
that if you do anything else, the reader will ask why; it
looks too much like a special case.
The result is that I do recomment things like:
while ( std::getline( source, line ) )...
even though I find them abhorant on a purely theoretical level.
While on this, for a less radical change. I've always wondered...
wouldn't it be fantastic if we could make cast operators in a
class explicit? As in:
class X
{
// ...
explicit operator int() const;
// ...
};
Where the explicit qualification indicates that the conversion
can only be used where an explicit cast is invoked? That is,
with the above:
X x;
int a = static_cast<int> (x); // is ok, but:
vector<int> a (x); // is not (requires implicit
// conversion to int)
The counter argument is that we already have this:
class X
{
// ...
ini asInt() const ;
// ...
} ;
Of course, the name isn't standard, and in templates, it isn't
the same as the name used for built-in types.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]