equality operator question

B

barcaroller

Is it now common practice to use conditional statements like

if (0 == i)
if (-1 == i)
if (true == i)
if (5 == i)

over the more traditional statements like

if (i == 0)
if (i == -1)
if (i == true)
if (i == 5)

for all types of 'i' (PODs and classes)?
 
J

Jim Langston

Jack said:
The reason for writing the constant first in an equality comparison is
quite simple. A fairly common typographical error is type only one
'=' once in a while when two are intended, and needed.

Consider the implications of accidentally typing:

if (i = 0)

...when you meant to type:

if (i == 0)

Assuming a built-in type, or even a class type having an assignment
operator accepting an int, then the first version, the type, is not
only always false, but it also destroys the existing value of 'i'. Yet
it is syntactically correct and swallowed by the compiler without
complaint.

On the other hand, if you accidentally type "if (0 = i), the compiler
will emit a diagnostic and reject it.

So it is a very inexpensive method of catching a typing error on the
very first compile. This is not an extremely common error, but is one
which happens to everyone once in a while. And of course it doesn't
help when you are comparing two objects, but comparisons with a
constant are fairly frequent.

Some programmers consider it hideously ugly and refuse to ever use it.
I think it is useful and I use it. It works, and it saves time when
you do happen to make that typo.

I agree, but my compiler warns me if an assignment is being made inside an
if statement. Otherwise I probably would use that format. But since it
does, I stick with the more traditional if ( variable == value )
 
K

kwikius

Jim Langston said:
Jack Klein wrote:


I agree, but my compiler warns me if an assignment is being made inside an
if statement. Otherwise I probably would use that format. But since it
does, I stick with the more traditional if ( variable == value )


Of course to address the problem effectively one could simply *replace* the
offending operators:

#define IS_EQUAL_TO ==

#define INITIALISE_WITH =

#define PLUS +

#define OUTPUT <<

#define CONTENTS_OF *

#define POINTER *

#define ADDRESS_OF &

#include <iostream>

int main()

{

int x INITIALISE_WITH 1;

int POINTER px INITIALISE_WITH ADDRESS_OF x;

if ( CONTENTS_OF px PLUS 1 IS_EQUAL_TO 2){

std::cout OUTPUT "Who needs operators?\n";

}

}



regards

Andy Little
 
J

James Kanze

Is it now common practice to use conditional statements like
if (0 == i)
if (-1 == i)
if (true == i)
if (5 == i)
over the more traditional statements like
if (i == 0)
if (i == -1)
if (i == true)
if (i == 5)
for all types of 'i' (PODs and classes)?

No. First of all, you never compare with true or false. As for
the others, I'd say that it is generally universal practice to
put the constant to the right of the comparision operator. I
don't know where this practice originated, but it certainly
predates C++, and there's no reason to do otherwise in C++.
 
P

Pascal J. Bourguignon

James Kanze said:
No. First of all, you never compare with true or false. As for
the others, I'd say that it is generally universal practice to
put the constant to the right of the comparision operator. I
don't know where this practice originated, but it certainly
predates C++, and there's no reason to do otherwise in C++.

The reason is that if you have a normal keyboard, without rebound,
you'll type:

if (i = -1) ...

and then the compilers won't complain and will generate:

{ i=-1;
... }

On the other hand, if you write:

if (-1 = i) ...

since -1 is not a LHS, -1=i is invalid and the compilers will signal
an error.


However, I cannot say that's it's common practice.
I prefer to write if(i==-1)...
and I just insert a grep in my makefiles to catch any assignment in
if, while or do conditionals.
 
J

James Kanze

The reason is that if you have a normal keyboard, without rebound,
you'll type:
if (i = -1) ...
and then the compilers won't complain and will generate:
{ i=-1;
... }

First, of course, I won't generally type that; I'll type:
if ( i == -1 ) ...
(with lot's of white space, so it's easy to see what each token
is). Second, if I do slip up, most compilers will warn, and of
course, the code will never get through code review, nor pass
any of the unit tests. So it's not really a big thing.
On the other hand, if you write:
if (-1 = i) ...
since -1 is not a LHS, -1=i is invalid and the compilers will
signal an error.

Which only works if you're comparing with a constant. On the
other hand, if I write:
if ( f() == x ) ...
rather than
if ( x == f() ) ...
I get the added check with the more natural form. So you force
an unnatural form to occasionally get the check, and more often
to not get it when you otherwise would.
However, I cannot say that's it's common practice.
I prefer to write if(i==-1)...
and I just insert a grep in my makefiles to catch any
assignment in if, while or do conditionals.

Automated code review:). Definitely a good idea.
 
P

Pascal J. Bourguignon

Krice said:
I'm doing that. What could go wrong?

Well, with false, not much wrong, since false must be == !true, and
if(false){this;}else{that;} must evaluate that, we're about certain
that false == 0.

But for true, it's something else. It may be 1, -1, 0xff, or whatever
not 0.

But in any case, it's harder to read boolean expression when you add
equivalences with the constants.

Compare:


Is it true that it is false that you're not big?
if(true==(false==(not(you->big())))){ fast();}

Are you big?
if(you->big()){ fast();}


Ok, even if you remove some == and some not, it's still harder to
understand the question:

Is it true that you're big?
if(true==you->big()){ fast();}
 
P

peter koch

I'm doing that. What could go wrong?

Probably nothing goes wrong although if (i == true) is to cryptic to
me when i is not boolean (in which case you should have written if (i
== 1). But the whole idea is one of obfuscation to me: if (i) serves
the purpose perfectly, and any extraneous comparison would get me
asking why, let me recheck the definition of i and (if I was a code
reviewer) return the code back to the OP.

/Peter
 
B

barcaroller

James Kanze said:
No. First of all, you never compare with true or false.

Why not? It's safer (and clearer) than using

if ( x )
if ( !foo() )


By using true/false, you are making it clear that you are dealing with a
boolean expression (as mostly intended) and not a variable/function that may
have any value.
 
C

Christian Hackl

barcaroller said:
Why not? It's safer (and clearer) than using

if ( x )
if ( !foo() )


By using true/false, you are making it clear that you are dealing with a
boolean expression (as mostly intended) and not a variable/function that may
have any value.

Isn't it a better idea to make that clear with the name? After all, you
wouldn't use "x" and "foo" as identifiers in a real program :)

if ( is_safe )
if ( !fileExists() )
 
J

James Kanze

Well, with false, not much wrong, since false must be == !true, and
if(false){this;}else{that;} must evaluate that, we're about certain
that false == 0.

False is equal to false. It's never 0, or any other numeric
value. If you convert a bool to another numeric type, false
converts to 0, but that's a different problem. (Also, you
rarely would convert a bool to any other numeric type.))
But for true, it's something else. It may be 1, -1, 0xff, or
whatever not 0.

True is true. It's never 1, -1, 0xff or whatevert. It's not a
numeric value.

False and true are values of type bool. Type bool has exactly
two values, false, and true, and no others. A expression of
type bool cannot have a value 0, or 1, or -1 or 0xFF or
whatever. It can only have a value of false or true.

In C++, for historical reasons, bool converts to numeric types,
with false converting to 0, and true to 1. In C++, for
historical reasons, numeric types and pointers convert to bool,
with the result being the same as if you'd compared them to 0.
These conversions are really only present for historical
reasons, however, and you don't use them in well written code.
But in any case, it's harder to read boolean expression when
you add equivalences with the constants.

The real problem is that it is redundant. Suppose you write
something like:

if ( a == true )

Presumably, a has type bool, or the expression doesn't really
make sense. (If a has type int, then the expression "true", of
type bool, will be converted to the integral value 1. If this
is what is wanted, it's obfuscation.) But of course, the
expression "a == true" also has type bool. So by the same
logic, if we wanted to test whether it was true, we'd write:

if ( (a == true) == true )

Except, of course, that "(a == true) == true" has type bool, so
we'll write...

A condition requires a bool (or something which converts
implicitly to bool). If you've got a bool, you've already got
what you need. If you don't have a bool, the comparison
operators (==, !=, > etc.) all result in a bool.
 
J

James Kanze

Why not? It's safer (and clearer) than using
if ( x )
if ( !foo() )
By using true/false, you are making it clear that you are
dealing with a boolean expression (as mostly intended) and not
a variable/function that may have any value.

How is it clearer? If the expression doesn't have type bool,
you shouldn't compare with true or false, but rather with
something of the correct type. If the expression has type bool,
there's no point in comparing, since the whole point of the
comparison is to get a type bool. And if you compare a boolean
expression with true or false, you'll never finish, because a
comparison is a boolean expression.
 
J

James Kanze

Why would anyone mix int with bool true or false?
[/QUOTE]
Often a function returns a value that indicates whether it
succeeded, and if not, an error code that indicates what the
failure was. Sometimes all you care about is whether it
succeeded. There's a long tradition in C and C++ of using this
kind of bool-and-a-half value.

But you wouldn't mix the int with true or false.

At least in the C/C++ communities I've been active in, the
largest single tradition involved defining sentinal values to be
used for an error: typically, a function which can only return
positive values will be declared to return an int, with -1 for
error. Which, of course, doesn't lend itself to an implicit
conversion, much less with comparison with true or false.

More recently, of course, Posix has adopted the tradition of
returning 0 for success, and a strictly positive error code for
error, so you could write:

if ( pthread_create( ... ) ) {
// Didn't work...
}

Which, of course, is exactly the opposite convention that one
finds in:

if ( std::getline( input, line ) ) {
// Worked...
}

Here too, however, you wouldn't mix with true or false; you
wouldn't write:

if ( pthread_create( ... ) == false ) {
// Worked...
}

(and of course:

if ( pthread_create( ... ) == true ) {
// Didn't work...
}

doesn't work at all.)

Globally, I find the convention of "true" for success slightly
more intuitive, but it doesn't leave any possibility for
additional error codes. I'll use the direct test on the
operation with iostream, because it is *the* standard C++ idiom,
but in all other cases, I'll use comparison.

At least where "simple" types are concerned. In more complex
cases, I've found it useful to return a class with the error
status and additional information. And to have the class
convert implicitly to bool. But here again: I only use the
conversion (the bool) for a direct check, where I don't need any
of the additional information---I don't compare the results with
true or false.
 
E

Eberhard Schefold

James said:
if ( (a == true) == true )

Except, of course, that "(a == true) == true" has type bool, so
we'll write...

The motivation for precisely one comparison with true seems rather
obvious to me -- human language. We say

If that expression is true, then ...

not

If that expression, then ...

nor

If that expression is true, is true, then ...

I'm not advocating to compare a bool value with true in an if clause,
but if somebody prefers that style, I don't see the need to talk them
out of it.
 
P

Pascal J. Bourguignon

Eberhard Schefold said:
The motivation for precisely one comparison with true seems rather
obvious to me -- human language. We say

If that expression is true, then ...

not

If that expression, then ...

nor

If that expression is true, is true, then ...

You have a strange human language. In the human languages I speak,
we usually say "If it is raining then we won't go outside." or "If it
is sunny then let's eat ice cream.".

We don't usually say "If it is true that it is sunny, then let's eat
ice cream.". Saying such a locution would indicate that you don't
know yourself whether it's sunny or not, that you have been told so,
and that you don't believe it.

I'm not advocating to compare a bool value with true in an if clause,
but if somebody prefers that style, I don't see the need to talk them
out of it.

Well of course, it's a question of style. If we had more powerful
editors(1), they could correct these stylistic variants as well as they
correct the indentation.



(1) actually, we have powerful enough an editor: emacs, the question
is whether we have enough time to customize it to do this kind of
things ;-)
 
L

Lionel B

The motivation for precisely one comparison with true seems rather
obvious to me -- human language. We say

If that expression is true, then ...

We we don't (at least I don't) say "If n is equal to 1 is equal to true,
then ..."
not

If that expression, then ...

I do say: "If n is equal to 1, then ..."

[...]
I'm not advocating to compare a bool value with true in an if clause,
but if somebody prefers that style, I don't see the need to talk them
out of it.

I might see the need to talk them into using more sensible variable
names: e.g.

if (need_user_input) ...

doesn't need an " == true" to make it human language-friendly.
 
E

Eberhard Schefold

Pascal said:
You have a strange human language. In the human languages I speak,
we usually say "If it is raining then we won't go outside." or "If it
is sunny then let's eat ice cream.".

if( a() == true )

rather reminds me of a human language sentence than

if( a() )

does. Yes, I perceive it that way -- no apologies.

I prefer the latter form in programming, but I can understand why some
people prefer the first.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top