As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I've been programming in C-derived languages for a couple of decades now. Somewhere along the line, I decided that I no longer wanted to write:
if (var) // in C
if ($var) # in Perl
when what I meant was:
if (var != 0)
if (defined $var and $var ne '')
I think part of it is that I have a strongly-typed brain and in my mind, "if" requires a boolean expression.
Or maybe it's because I use Perl so much and truth and falsehood in Perl is such a mine-field.
Or maybe it's just because these days, I'm mainly a Java programmer.
What are your preferences and why?
I like my ifs to make sense when read aloud:
if (is_it_happening) ...
if (number_of_sheep != 0) ...
if (pointer_to_something != NULL) ...
I prefer
if (var != 0)
It's easier to read/understand. Since you write the code once but read quite a few times, easy reading is more important than easy writing.
It's quite simple. if( var ) tests for truthiness. if( var != 0 ) tests that it's not the number 0. THEY ARE NOT INTERCHANGABLE! There are three reasons.
First, using if( var != 0 ) to test for truth is more complicated. There's simply more there to read and understand. You have to grok that != and 0 is the idiom for "is true". Lacking a distinctive visual pattern, you have to do a little more studying to know that it's not the same as if( var == 0). This is a thin distinction, but worth mentioning. The fact that the if( 0 != var ) style exists gives credence. Better to just eliminate the problem and use if( var ) for truthiness.
Second, and more importantly, the intent must be clear. Are you testing for truth or are you testing for a number (or lack thereof)? if( var ) is testing for truth, if( var != 0 ) is testing a number. To determine anything else requires having knowledge of the author's style, which we must assume the maintenance programmer does not.
Third, there is an assumption here about the value of true and false and numeric operators which might work out in some languages and not in others. In Perl, and I think Javascript, too, empty string is false. A lot of operators return empty string for false. So testing truth with if( var != 0 ) leads to a warning. It becomes more stark when you do something more naive like if( var == 1 ) to mean truth, a clearly dangerous assumption. I have seem many junior programmers write that and in turn written functions that return odd, but true, numbers to punish this sort of thing. Or when I'm in a giving mood, I've sanitized my return value with return var ? 1 : 0.
In a related note, Perl will return the last evaluated expression from a subroutine, so it's not necessary to actually write return. Combine this with the idea people have that explicit return is slower and you get a lot of people abusing this fact.
sub set {
my( $self, $key, $value ) = #_;
$self->{$key} = $value;
}
set will return $value. Was that intended? I don't know. What I do know is someone will start relying on it. And the maintenance programmer won't know if they can change it. So I like to explicitly put a return in every non-trivial subroutine.
sub set {
my( $self, $key, $value ) = #_;
$self->{$key} = $value;
return;
}
In that case I decided set will return nothing for the time being and that decision will be quite clear to both the reader and the user.
if (var)
Less to type, as long as you're sure you're not testing the wrong thing.
I prefer explicit tests unless the result inside the parentheses is a explicit boolean. The phrase "if (1)", while syntactically and semantically correct in terms of the language, is not logical. It should be true or false, not cast automatically.
I prefer readable logical code to less typing any day.
I also despise vehemently code of the form:
if (gotError == FALSE) ...
if (isComplete == TRUE) ...
If the boolean value is properly named (and it should be), the right way to do that is:
if (!gotError) ...
if (isComplete) ...
That's because (using reductio ad absurdum) boolVal == TRUE is simply another boolean value, so where do you stop?
if (isComplete == TRUE) ...
if ((isComplete == TRUE) == TRUE) ...
if (((isComplete == TRUE) == TRUE) == TRUE) ...
if ((((isComplete == TRUE) == TRUE) == TRUE) == TRUE)...
And so on, ad infinitum.
I would say that if you are comparing a true integer, then never do an implicit conversion to boolean, as it implies a different meaning to the variable.
But then again that style is so popular is probably isn't too big of a deal, but from my work with C#, I write my C++ code in this style:
Boolean or int that is basicaly a boolean:
if (val)
True integer with more than true/false being important:
if (val != 0)
Pointer of some kind:
if (val != NULL)
But as many people will say about coding styles that make no functional difference, it is probably best of all to be consistent, and if you are working with existing code, be consistent with that code.
In Perl if (defined $var and $var ne '') and if( $var) are NOT equivalent. Try it with $var=0. Conversely if you test on $var!=0 all strings that cannot be converted to numbers will fail the test (with a warning if you have them on).
So you must know exactly what your variable contains (number or string, whether it can be undef) so you can test accordingly.
I usually just write if( $var) and let Perl take care it. I believe that's easier to read, and that's the most common style in Perl.
Very often, actually, the proper test ends up being if( defined $var). That's where perl's new (in 5.10) // operator comes in handy. $var= $val // $default or often $var //= $default, where $var will receive $default only if $val (resp $var) is undef.
In Javascript (I don't know about other dynamic languages)
if (x)
and
if (x != 0)
mean different things. I will use the former when the I expect x to hold a reference to an object or string that should not be zero length. Its a well known enough idiom.
If you have a value that is intended to be a boolean, you should feel comfortable just doing:
if ( var )
if ( $var )
If you have more specific requirements for your "boolean," you can always do some prep work/tests on your variable and assign it to another variable with better defined boolean values.
$shouldDoSomething = ( defined $var and $var ne '' ) ? 1 : 0;
if ( $shouldDoSomething ) {
// Handle this case.
}
This can clean up the code quite a bit. It also helps if you intend to use this condition more than once. I find this happens pretty frequently, actually. Also, I feel like the above is far more readable than doing it inline:
if ( defined $var and $var ne '' ) {
// Handle this case.
}
I go with readability like most people, I like being able to scan my code and read it without having to think too much, it goes hand in hand though with well named variable names. If your variable names make it sound like it should be a plain if(isPurchasable) then I go with it however it referes to a number or date or similar fasion I use if(stock > 0).
Having to write a comment for an if statement too me is a horrible idea if the expression is so simple, an if statement like below though I can see why comments should be used.
if(isPurchasable && stock > 0 && credit >= cost && !reserved) {
// Checks to see if customer can purchase product.
}
For numeric value scalars, I tend to write if ( $num_foo ) when $num_foo is in my control. If it’s user input or passed in from outside I either numify it first or spell out the test explicitly. It depends on a lot of factors. The main criterion is when and how it’s convenient to deal with undefined values, in order to avoid warnings.
To test for non-empty string, I used to write if ( $foo ) because the correct incantation is just way too much typing:
if ( defined $foo and length $foo )
But I wasn’t satisfied with this state of affairs so I instigated a change of behaviour for length undef in Perl 5.12, which throws a warning and returns 0 up to Perl 5.10 inclusive. In 5.12 it will just silently return undef. Therefore in non-boolean contexts you still get a warning, it just happens after the length call is evaluated rather than before. But in boolean contexts, there is no warning, so checking for a non-empty string is much easier to do correctly:
if ( length $foo )
I have a bunch ways of doing it:
for booleans:
if (x)
for ints:
if (x != 0) // always compare, never assume true/false on int values
for pointers:
if (x /* != 0 */) // I've always done this, not sure where I picked it up but I like it
These days, I think it's nicer to have a function call which describes what the logic actually means within the if statement
EDIT: Note, the 0 (intsead of NULL) is because I mainly use C++ these days
I'm surprised nobody's mentioned the other option, which the coding standards at a past employer of mine advocated:
if( 0 != x );
Where the constant was always listed first (especially more important with comparisons as they occasionally get typo'd to assignments - the source of many a bug)
It's the style I've used ever since in my C / Perl / C++ / VB.Net since (obviously the point becomes moot in C# whihc doesn't actually allow the if (x) scenario (unless x is actually a boolean, of course).
In C# it has been made explicitly illegal to write
if(x){}
unless x is a boolean type. There is no implicit conversion to bool from most other types.
I used this form a lot writing JavaScript, PHP and such to check for non null. But then again, I did get a few (easily detectable) bugs from it... I guess we are better off without it.
When using it on boolean variables, I strongly believe in easily readable names. I usually name boolean variables used like that with names beginning with "is", "has" or something similar.
I generally prefer if (var) or if ($var) if var is used as a boolean, even if there isn't any such type in the language.
I very much dislike constructs like if (!strcmp(...)) or if (var == true). The first tries to be too smart, the second too dumb -- although it scales well to if ((var == true) == true), ... ;-)
Some languages, like Perl and C++, provide extra or even user defined interpretations of trueness. If the conversion to a boolean seems too magic, remember it's basically just an is_true(var) or var.booleanValue(), or something like that behind the scene, just a more concise syntax.
Related to your question, I like to formulate conditions in a positive way. Instead of
if (!condition) {
g();
}
else {
f();
}
I prefer
if (condition) {
f();
}
else {
g();
}
Even if there is only a single branch, and the condition is not terribly simple. (An indication for that is the need for a comment.) For example, instead of
// explain reason for condition here
if (!condition) {
f();
}
I prefer to phrase it as
if (condition) {
// explain condition here
}
else {
f();
}
To my way of thinking, simplicity is best.
The simpler you make the code, the better. Also, the less likely you'll make mistakes. Therefore, I would use
if(var)
But in the end, you should use what works best for your own way of thinking.
I don't always manage it, but I try to use
if (0 != var)
so it matches the defensive style
if (0 == var)
If you've got an int-bool in C that already holds a flag (and not a count), and you're testing it with "if (var != 0)", where does it end? Wouldn't "if ((var != 0) != 0)" be even better? :-)
I prefer a bare:
if ($canDo) {
}
instead of something like:
if ($canDo == true) {
}
Where a conditional is at all tricky, I comment it either explicitly with a comment, or implicitly with a good variable name. I also try to be very explicit when setting a boolean variable, preferring:
my($canDo) = !0;
to
my($canDo) = 1;
The latter is confusing; why assign a discrete value to a boolean?
Given Perl's many meanings to "evaluates to true", though, I can see why being more explicit is more practical in the long run. Still, one of the things I most like about Perl is its natural linguistic fluidity, and I prefer in my code to stick to that (leaving the comments and variable names to further clarify things, if needed).
VBScript? Well this bit of code declares a Variant, so bFlag is zero, which is effectively a False.
Dim bFlag
If bFlag Then
I don't like that. So even in VB, with the option of more specific declarations, I find myself being explicit no matter what the type.
Dim bFlag As Boolean
If bFlag = False Then
The other issue related to variable naming rules. If you're using an Hungarian-influenced regime, then you can tell visually that a given variable is boolean, so being specific about whether it's true or false is less of an issue. If, however, you're using some other variable naming technque, or worse, naming in an ad hoc way, then being specific about what's being tested for is appropriate.
Very often I use:
if(x) {
DoSomething;
DoSomething2;
}
Because this is less writing, and book which reading said:
Few good programmers use form if(x!=0), they use if(x).
But sometimes use and other form:
if(x!=0)
HNY! :-)
I find that if(X) { /* ... */ } is much easier to read (in C, at least).
If i don't expect anyone else to read the code, I'd us the short one.
If I expect someone to actually read my code, I would consider using the long form for readability.
I like Python constructions:
if var:
return "I like the way I do it!"
It's just for example ;-)
There are languages in which you have no choice. In Specman, for instance, you can't write:
var x: uint;
if (x) {
bla
};
But you can do:
var x: uint;
if (x != 0) {
bla
};
or
var x: bool;
if (x) {
bla
};
However, you can't do:
var x: bool;
if (x != 0) {
bla
};
Because you can't compare a boolean to an integer.
Coming from C and Perl I always thought this to be annoying, until I actually started writing a lot in Specman. The code is simply clearer like this.
In my opinion, if (var != 0) is better.
Related
I modified some chip manufacturer example code to remove a bunch of what I thought were stupid boolean comparisons, such as:
if(var == TRUE) → if(var)
if(TRUE == var) → if(var)
if(var != TRUE) → if(!var)
if(FALSE == var) → if(!var)
if(TRUE == var1 || TRUE == var2) → if(var1 || var2)
if(func() != FALSE) → if(func())
if(func() == TRUE) → if(func())
Where:
#define TRUE 1
#define FALSE 0
I thought this would make the code more readable and maybe even allow the compiler to optimize a little better, but the compiled code size increased by 118 bytes.
Am I missing something? These should be logically equivalent, right?
Ah, this is from the top of my head, but:
8051 has an instruction to jump conditioned on a single bit in a register, JB and JNB. If your compiler knows which bit to check, it can use that.
Alternatively, you can check the value in the accumulator being 0 or not 0, JZ, JNZ. But for that to work you might need to put the value on the accumulator first, which might need clearing and moving to that, adding overhead.
If your compiler isn't very old-school, use the built-in but not very standard _Bool or similar "pseudotypes", for which your compiler will work as smart as it can (and probably do what you intended to do).
Not only is it unnecessary, it is a bad idea. Only comparison to FALSE is safe, since any non-zero value is implicitly true, but comparing such a value to TRUE may fail.
You did the right thing. Although you may need to consider maintenance. If the vendor updates this code, you may have to re-apply all your changes. Often it is simpler to live with third-party code as-is; no such code is ever going to confirm to your specific local coding standards or style - probably in moor ways than just this. Live with it or don't use it; certainly do not copy it.
In your own code you'd do better to use stdbool.h and bool, true and false. But you should still avoid explicit tests since it is unnecessary.
What I would avoid is implicit conversions to bool however. So for example a non-null pointer test should be if( ptr != NULL) rather than the common idiom if( ptr ). The 'rule' being that the condition expression should be explicitly Boolean. In your case if var is Boolean then there is no need to test for equality to true/false. Conversely if var is not Boolean, then you should test using the Boolean expressions 0 == var/0 != var.
The advice is largely about code quality, robustness, clarity and maintainability. I doubt that it will have any impact on code generation in any reasonable compiler.
Is there any particular reason for != to be used more than ==?
I have noticed that != seems more common, but wondered if there was a reason for this.
If you have code like this:
if (a == b)
{
// block 1
}
else
{
// block 2
}
It can be rewritten as:
if (a != b)
{
// block 2
}
else
{
// block 1
}
These two examples do the same thing. Neither is more efficient than the other. If one is used more than the other it may be personal preference.
You should use == or != according to the logical condition you are trying to express. If you care about both the true and false conditions, i.e. both the if and else parts then the net effect of switching (if it's a simple comparison) is just which code needs to appear in which part.
There is a coding style, see (the book) Code Complete's section on Forming Boolean Expressions Positively which suggests that boolean expressions that express something positive are easier to understand than those expressing something negative.
If you only care about the condition when it evaluates to true, e.g. you only care when you have equality (for ==) or do not have equality (for !=) then you'll not require an else section if you pick the correct one.
Most of the time the preference of using != or == will depend on the content:
resultOfOperationOrCall = operationOrCall(...);
if (resultOfOperationOrCall != somePredefinedErrorTypeValue) {
// Normal processing
} else {
// Exception/error processing
}
Here using != is logically clearer than using ==
I prefer != because it's more explicit (and there is less chances to write = as mistake).
As assembly code for both == and != present so no issue of efficient or inefficient code for x86 architecture.So it is up to you .you can use any one of them.
if for some machine if assembly code not available then efficient or inefficient comes it to picture as that is achieved by compiler by performing some additional operation(that is adding additional assembly code).
Its wholly and solely depends on the perception & need of user. I don't see any reason on why would one use != more than ==
When I wish to check if a value is 0 in C, how is it idiomatically done?
if (!num)
if (num == 0)
While this is a matter of taste, I find it pretty much depends on intention. If the value is to be used as a boolean, ! is alright. If the value is counting something the equality makes more sense.
if (!isVisible) {...}
if (isVisible == 0) {...} // Intention not as clear as line above.
if (numberOfItems == 0) {...}
if (!numberOfItems) {...} // Intention not as clear as line above.
I always prefer the second way:
if (num == 0)
As num == 0 or ptr == NULL evaluates to a boolean which is the intent. The Java compiler enforces this form, but C/C++ compilers don't.
The worst example of this would be:
if (!strcmp(str, "something"))
Which really disguises its intent as the strcmp family of functions don't return boolean, they return positive, zero, or negative (as pointed out by #JoachimPileborg).
However if the int is being used to represent a boolean type, which C does not have a builtin type for, then this form is OK:
if (!b)
But this can be made self documenting by creating a custom type:
typedef int bool;
#define true 1
#define false 0
bool b = true;
if (!b)
{
... etc
}
Whatever the others told you WITH AN EXCEPTION!
Don't do it with float and double. IEEE 754 floats/doubles/long doubles (the most commonly used) often don't contain exact values, so comparing them directly with 0 is foolish (or doing if (!floatValue))
Example: http://ideone.com/PIUflA
float f = 0.3;
f -= 0.2;
f -= 0.1;
if (!f)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
if (f == 0)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
With unoptimized compilation can return (on ideone does)
non zero
non zero
(if you enable optimizations, the compiler could pre-compute some values in higher precision and round them to 0)
I think it depends on the context. If the variable refers to a boolean value is better first choice. Otherwise, the second is better.
It's done however you want it to be done, in terms of your style. I don't see it as mattering as long as your consistent and it's clear on what you're trying to do, or if you do it in cases where it may flow better in an English sentence and may put emphasis on what your doing.
For sake of clarity I usually have if (num == 0), since it takes less thinking to understand what I'm doing when I'm going over my code.
!!value will work too if you want to check if value is non-zero.
!value evaluates to 1 when value=0 and 0 when value≠0.
The second ! flips it, making !!value evaluate to 1 when value≠0 and 0 when value=0.
We may argue which way is better, but idiomatic, though for what I can tell by other answers archaic, would be if(!num).
For the compiler, it does not matter, of course. For the human reader it does. Since both forms are used by other human beings, you should get used to them and recognise them. Personally, I prefer the shortest form, which takes less time (less tokens, especially parenthesis) to read and understand. Especially:
if (!ptr) {}
if (!strcmp(a,b)) {}
are easyer to read than
if (ptr != NULL) {}
if (strcmp(a,b) == 0) {}
if (0 == strcmp()) {}
The last form makes me physically sick.
I saw this code today :
if(++counter == 10)
{
//Do Something
foo();
}
I think this is bad style, but, is the execution compiler dependent aswell? say the counter is set to 8 before we get to this line, it's going to increment it, then compare 10 to 8, the value before, or compare 10 to 9, the value of counter after it got incremented?
What do you think SO? Is this common practice? bad style?
There's nothing compiler-dependent in the behavior of this code (besides possible overflow behavior). Whether it is a good style is a matter of personal preference. I generally avoid making modifications in conditionals, but sometimes it can be useful and even elegant.
This code is guaranteed to compare the new value to 10 (i.e. 9 is compared to 10 in your example). Formally, it is incorrect to say that the comparison takes place after counter gets incremented. There's no "before" or "after" here. The new value can get pre-calculated and compared to 10 even before it is physically placed into counter.
In other words, the evaluation of ++counter == 10 can proceed as
counter = counter + 1
result = (counter == 10)
or as
result = ((counter + 1) == 10)
counter = counter + 1
Note that in the first case counter is incremented before the comparison, while in the second case it is incremented after the comparison. Both scenarios are valid and perfectly possible in practice. Both scenarios produce the same result required by the language specification.
Operator precedence will always cause the increment to take place before the comparison. You may use parenthesis if you wish to make this very explicit, but I wouldn't call this bad coding style.
Personally I'd always separate this into two statements.
counter++;
if (counter == 10)
DoSomething();
This way you don't need to think about what order things happen—there is no scope for confusion. It makes no difference to the generated code and when that is so, readability and maintainability concerns are always king.
It is well defined by the language standard, and whether it is a bad style or not is a matter of a personal preference, and of a context as well. I have one function using conditions similar to this, which I think looks and works very nice, and which I think would be less readable when the increment would be taken out of the condition.
const char *GetStat(int statId)
{
int id = 0;
if (statId==id++)
{
return "Buffers";
}
else if (statId==id++)
{
return "VBuffers";
}
#ifndef _XBOX
else if (statId==id++)
{
return "Reset factor";
}
#endif
else if (statId==id++)
{
return "CB Mem";
}
return "";
}
Note: the increments are actually not "performed" at all here, a decent compiler will eliminate the ++ done on id variable into constants.
Is there a difference in the order of the comparison operator?
#define CONST_VALUE 5
int variable;
...
if ( variable == CONST_VALUE ) // Method 1
...
OR
if ( CONST_VALUE == variable ) // Method 2
...
Is this simply a matter of preference or is there a compelling reason for a particular comparison order?
The reason some people use method 2 is because you'll get a compiler error if you mistype a = in place of the ==.
However, you'll have people (like me) who will still use method 1 because they find it more readable and if there is an error, it will be detected during testing (or, in some cases, static analysis of the code).
The only difference is that ( CONST_VALUE == variable ) makes the common typo ( CONST_VALUE = variable ) impossible to compile.
By comparison, if ( variable = CONST_VALUE ) will result in the compiler thinking you meant to assign CONST_VALUE to 'variable'.
The =/== confusion is a pretty common source of bugs in C, which is why people are trying to work around the issue with coding conventions.
Of course, this won't save you if you're comparing two variables.
And the question seems to be a duplicate of How to check for equals? (0 == i) or (i == 0)
And here's some more information: http://cwe.mitre.org/data/definitions/481.html
As others mentioned, CONST_VALUE == variable avoids the = typo.
I still do "variable == CONST_VALUE", because I think its more readable and when I see something like:
if(false == somevariable)
my bloodpressure goes up.
The first variant
if (variable == CONST_VALUE)
is better, because it is more readable. It follows the convention (also used in mathematics) that the value that changes most comes first.
The second variant
if (CONST_VALUE == variable)
is used by some people to prevent a mixup of equality checking with the assignment
if (CONST_VALUE = variable)
There are better ways to achieve that, for example enabling and taking heed of compiler warnings.
Others already pointed out the reason. = / == confusion. I prefer the first version because it follows the thought process more closely. Some compiler alleviate the confusion of = and == by giving a warning when it encounters something like
if(a=b)
in this case if you really wanted to do the assignation you're forced to write
if((a=b))
which I would write then as
if( (a=b) != 0)
to avoid the confusion.
This said, we had in our code 1 case where we had a =/== confusion and writing it the other way round wouldn't not have aided as it was a comparison between vars.