Are multiple conditional operators in this situation a good idea? - c++

I just saw this block of code on the Wikipedia article on conditional operators:
Vehicle new_vehicle = arg == 'B' ? bus :
arg == 'A' ? airplane :
arg == 'T' ? train :
arg == 'C' ? car :
arg == 'H' ? horse :
feet;
I've changed the code a little, but the idea is the same. Would you find this use of the conditional operator acceptable? It's much more concise than the if-else construct, and using a switch would definitely open up a whole new set of opportunities for bugs (fall-throughs anyone?). Also, if-elses and switch can't be used as R-values, so you'd have to create the variable first, initialize it and then assign as necessary.
I for one really like this, but I'm wondering what others think.
But the formatting is essential.
EDIT: I still like this. But I understand those who say "the switch statement was made for this". OK, maybe so. But what if the conditions are function calls that return bool? Or a million other things you can't switch on.
Are you switch lovers really trying to convince me that a huge if-else chain is better? Yes, programmers who don't know how to use the conditional operator will not understand this. They should learn how to use it. It's not arcane.

I have used this type of construction many times. As long as it's formatted nicely (i.e. not all on one line, making it unreadable), I don't see a problem with it.

I would use a switch, because this is the kind of thing it was designed for. Yes, there is a risk of fall-through bugs, but this nested-conditional block has a much higher risk of being misunderstood by other programmers.

This is a great example of conditional operator use. I use it in this manner all the time in C++, Java, and Perl.

Not only is there nothing wrong with it, it communicates the intent of the operation in the most concise and clear way possible.
Replacing with if else, or switch construction requires that the snippet
"new_vehicle = "
be repeated in every instance, which requires that the reader read every repeating instance of it to ensure that it is in fact the same in every instance..

I like it. It is similar to an if-else-if ladder, only more concise.

There's a lot of whitespace around the character constants that makes it a bit hard to read. I'd parenthesize the comparisons: (and maybe move the last value in line.)
Vehicle new_vehicle = (arg == 'B') ? bus :
(arg == 'A') ? airplane :
(arg == 'T') ? train :
(arg == 'C') ? car :
(arg == 'H') ? horse :
feet;
Now it looks great.

The conditional operator version is clean, simple, and it's immediately obvious to anybody who knows C or C++ what is happening. Its other virtue is that it returns a value immediately, which means it can be put in the initialization (like this example is).
A switch statement would be more clumsy. It would require that the variable be declared and then initialized, usually a bad idea if it can be avoided. It would take more typing, and would have more places for bugs to creep in. It wouldn't be as clear, since it would be necessary to look at each case to see that it said something like new_vehicle = foo; break;.
If you're going to do this look up here only, then having the conditional version right there is good, as it immediately shows what's happening. If it's going to occur more than once, consider putting it in a function, so that there's only one place to update if anything changes (such as, say, 'R' for carriage or 'L' for helicopter).

Purely a stylistic choice. For small data sets like you present here, then as long as your programming team isn't thrown by such a thing, then its fine in my book.

A switch is both clearer and possibly much more efficient. If I saw code like this at a code review, I'd be worried. Also, this is "the conditional operator" - it is an instance (albeit currently the only one in C and C++) of a ternary operator.

Vehicle new_vehicle = getVehicleByType(arg);
Vehicle getVehicleByType(char arg){
if (arg == 'B') return bus;
if (arg == 'A') return airplane;
if (arg == 'C') return car;
if (arg == 'T') return train;
if (arg == 'H') return horse;
return feet;
}
I like this better. The nested conditional is clever, but I think this is almost as concise and less likely to confuse a future reader. Sorry if the syntax is off, I'm not doing much C nowadays.
EDIT: Fixed return type omission noted in comments. thx!
EDIT: I'm not horrified at your version by the way. I did not exclaim WTF or OMG when i saw it. I just prefer mine a little more :)

I don't particularly care for it.
It doesn't really buy anything, or make anything more clear, and it's a pretty non-standard usage of the operator.
It seems the primary advantage is that it's somewhat clever. I avoid clever unless there's a pretty good (external) reason to be clever.

I would lean toward a switch statement because the compiler will catch duplicate cases. Arguably, this is not an issue in this example but if the list gets really long and is worked on by several different people it is easy to add a duplicate and not realize it.

Read the C++ section of the Wikipedia article a bit more carefully. It explicitly lists some situations where using the ?: operator is the only option, and can't be replaced by if/else or switch.
On the other hand, I wouldn't use it only because it looks prettier.

I've never seen anything written like this before. While it is clever and well-formatted, this seems like the perfect opportunity to use a dictionary/hashtable (assuming Vehicle is an enumeration, which is unclear).

A few people have already mentioned the possibility of using an std::map or other associative array type to do the job. As long as you're only doing this is one place (or a few places), you might consider just using a normal array or vector instead:
Vehicle vehicles[CHAR_MAX];
// Initialization
std::fill_n(vehicles, CHAR_MAX, feet);
vehicles['A'] = airplane;
vehicles['B'] = bus;
vehicles['C'] = car;
vehicles['H'] = horse;
vehicles['T'] = train;
// Use
Vehicle new_vehicle = vehicles[arg];
Depending on how may tables you need/use (that store the same type of object), and the size of the contained objects (Vehicle in this case), this can be a perfectly reasonable alternative to an std::map. If you're creating a lot of tables, or each object is really big, std::map becomes a more reasonable alternative.
When you use an std::map (or unordered_map, etc.) you're using more code to save on data storage. This does the reverse -- but as long as Vehicle is small (say, 4 bytes), one table like the above will typically occupy something like half a kilobyte. It's hard to guess exactly how large the code for std::map is going to be for a specific compiler, but it seems likely that it'll usually be larger than half a kilobyte, so if you're only creating one table like this, std::map may be a net loss.
Of course, if you know that you're only dealing with letters as input, you could reduce the table size quite a bit:
template <class T>
class letter_table {
static const int range = 'Z' - 'A';
T table[range];
public:
// ...
T operator[](int index) {
index -= 'A';
assert(index<range);
return table[index];
}
};
In the example case, this would give a table around 100 bytes -- you can create a pretty fair number of 100-byte tables in the space std::map will normally occupy.

Purely practical:
Plus: The ternary sequence is more flexible, and can be used to avoid the limitations of switch, you could use other operators (e.g. <=, >=) or any other tests, including e.g. string comparisons.
x = IsEven(arg) ? 0 :
(arg < 0) ? -1 : 1; // or whatever
Also, if the switch is a performance bottleneck and you have uneven probabilities, you can force the likeliest tests being done first (due to the not evaluated guarantee for the path not chosen).
So-So
Unlike a switch statement, order is important (unless you stick to ==). That can be an advantage, but being otherwise similar to switch that might be misleading when the maintainer is unfamiliar with the concept or in a hurry.
Many developers may shy away because they aren't sure about the details (which terms will be evaluated, is the rpecedence of the operators ok?) - However, if your developer pool won't grasp a well-presented example, you might have problems that can't be solved by banning ternary operators.
Minus
It isn't as common as switch, thus the optimizer might not treat it the same. Optimizers are know to select the best fit implementation for a switch (table, binary search, comparison sequence, or any combination of this). Optimizers can't reaarange wevaluaiton order, and are less likely to support a table lookup here.
Requires good formatting to be easily recognizable (lining up the '?' and ':') - Sucks when you use tabs.
Aesthetics
I like it for its precision and succinctness, close to mathematical notations. However, that might as well be used against it. It's probably an eyebrow raiser at code reviews, because it is less common and more brittle.

Just for comparison, in C++0x you can have an expression without using the conditional operator or an out-of-line function:
Vehicle new_vehicle = [&]() -> Vehicle {
if (arg == 'B') return bus;
if (arg == 'A') return airplane;
if (arg == 'T') return train;
if (arg == 'C') return car;
if (arg == 'H') return horse;
return feet;
}();
Not really any better, though.

How about:
enum Vehicle { bus = 'B', airplane = 'A', train, car = 'C', horse = 'H', feet = 'F' };
...
new_vehicle = arg;
:-), by the way.

I think its useful for someone who code it, but will be difficult to understand for the reviwer,
"KEEP IT SIMPLE BUDDY"

In my opinion what you've done is acceptable due to the simplicity of the example. If you were doing more things with each case this type of construct could rapidly get messy. For that reason I would prefer a switch or even nested if then elses (if there aren't too many cases), formatted as follows:
if (A) {
//Do A stuff
}
else if (B) {
//Do B stuff
}
else if (C) {
//Do C stuff
}
else {
//Do default stuff
}
It's about the readability of the code, which lends itself to the maintainability of the code. I've never been a huge fan fan of the conditional operator, because I don't like to see multiple expressions on a single line. Conditional operators can be difficult to follow when single stepping the code in a debugger. The simpler the code the easier it is to concentrate on what the code is doing.

Many of us are used to the Iif-functions in various reporting tools or the If-function in Excel where we basically need to use the less clear Iif(arg="B";"Bus";Iif(arg="A";Airplane;"Feet")). I love your sample compared to that :)
I personally would've used if-elses, but I would not have a problem with your sample.

Related

Is it a good style to write constants on the left of equal to == in If statement in C++? [duplicate]

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.
Okay, we know that the following two lines are equivalent -
(0 == i)
(i == 0)
Also, the first method was encouraged in the past because that would have allowed the compiler to give an error message if you accidentally used '=' instead of '=='.
My question is - in today's generation of pretty slick IDE's and intelligent compilers, do you still recommend the first method?
In particular, this question popped into my mind when I saw the following code -
if(DialogResult.OK == MessageBox.Show("Message")) ...
In my opinion, I would never recommend the above. Any second opinions?
I prefer the second one, (i == 0), because it feel much more natural when reading it. You ask people, "Are you 21 or older?", not, "Is 21 less than or equal to your age?"
It doesn't matter in C# if you put the variable first or last, because assignments don't evaluate to a bool (or something castable to bool) so the compiler catches any errors like "if (i = 0) EntireCompanyData.Delete()"
So, in the C# world at least, its a matter of style rather than desperation. And putting the variable last is unnatural to english speakers. Therefore, for more readable code, variable first.
If you have a list of ifs that can't be represented well by a switch (because of a language limitation, maybe), then I'd rather see:
if (InterstingValue1 == foo) { } else
if (InterstingValue2 == foo) { } else
if (InterstingValue3 == foo) { }
because it allows you to quickly see which are the important values you need to check.
In particular, in Java I find it useful to do:
if ("SomeValue".equals(someString)) {
}
because someString may be null, and in this way you'll never get a NullPointerException. The same applies if you are comparing constants that you know will never be null against objects that may be null.
(0 == i)
I will always pick this one. It is true that most compilers today do not allow the assigment of a variable in a conditional statement, but the truth is that some do. In programming for the web today, I have to use myriad of langauges on a system. By using 0 == i, I always know that the conditional statement will be correct, and I am not relying on the compiler/interpreter to catch my mistake for me. Now if I have to jump from C# to C++, or JavaScript I know that I am not going to have to track down assignment errors in conditional statements in my code. For something this small and to have it save that amount of time, it's a no brainer.
I used to be convinced that the more readable option (i == 0) was the better way to go with.
Then we had a production bug slip through (not mine thankfully), where the problem was a ($var = SOME_CONSTANT) type bug. Clients started getting email that was meant for other clients. Sensitive type data as well.
You can argue that Q/A should have caught it, but they didn't, that's a different story.
Since that day I've always pushed for the (0 == i) version. It basically removes the problem. It feels unnatural, so you pay attention, so you don't make the mistake. There's simply no way to get it wrong here.
It's also a lot easier to catch that someone didn't reverse the if statement in a code review than it is that someone accidentally assigned a value in an if. If the format is part of the coding standards, people look for it. People don't typically debug code during code reviews, and the eye seems to scan over a (i = 0) vs an (i == 0).
I'm also a much bigger fan of the java "Constant String".equals(dynamicString), no null pointer exceptions is a good thing.
You know, I always use the if (i == 0) format of the conditional and my reason for doing this is that I write most of my code in C# (which would flag the other one anyway) and I do a test-first approach to my development and my tests would generally catch this mistake anyhow.
I've worked in shops where they tried to enforce the 0==i format but I found it awkward to write, awkward to remember and it simply ended up being fodder for the code reviewers who were looking for low-hanging fruit.
Actually, the DialogResult example is a place where I WOULD recommend that style. It places the important part of the if() toward the left were it can be seen. If it's is on the right and the MessageBox have more parameters (which is likely), you might have to scroll right to see it.
OTOH, I never saw much use in the "(0 == i) " style. If you could remember to put the constant first, you can remember to use two equals signs,
I'm trying always use 1st case (0==i), and this saved my life a few times!
I think it's just a matter of style. And it does help with accidentally using assignment operator.
I absolutely wouldn't ask the programmer to grow up though.
I prefer (i == 0), but I still sort of make a "rule" for myself to do (0 == i), and then break it every time.
"Eh?", you think.
Well, if I'm making a concious decision to put an lvalue on the left, then I'm paying enough attention to what I'm typing to notice if I type "=" for "==". I hope. In C/C++ I generally use -Wall for my own code, which generates a warning on gcc for most "=" for "==" errors anyway. I don't recall seeing that warning recently, perhaps because the longer I program the more reflexively paranoid I am about errors I've made before...
if(DialogResult.OK == MessageBox.Show("Message"))
seems misguided to me. The point of the trick is to avoid accidentally assigning to something.
But who is to say whether DialogResult.OK is more, or less likely to evaluate to an assignable type than MessageBox.Show("Message")? In Java a method call can't possibly be assignable, whereas a field might not be final. So if you're worried about typing = for ==, it should actually be the other way around in Java for this example. In C++ either, neither or both could be assignable.
(0==i) is only useful because you know for absolute certain that a numeric literal is never assignable, whereas i just might be.
When both sides of your comparison are assignable you can't protect yourself from accidental assignment in this way, and that goes for when you don't know which is assignable without looking it up. There's no magic trick that says "if you put them the counter-intuitive way around, you'll be safe". Although I suppose it draws attention to the issue, in the same way as my "always break the rule" rule.
I use (i == 0) for the simple reason that it reads better. It makes a very smooth flow in my head. When you read through the code back to yourself for debugging or other purposes, it simply flows like reading a book and just makes more sense.
My company has just dropped the requirement to do if (0 == i) from its coding standards. I can see how it makes a lot of sense but in practice it just seems backwards. It is a bit of a shame that by default a C compiler probably won't give you a warning about if (i = 0).
Third option - disallow assignment inside conditionals entirely:
In high reliability situations, you are not allowed (without good explanation in the comments preceeding) to assign a variable in a conditional statement - it eliminates this question entirely because you either turn it off at the compiler or with LINT and only under very controlled situations are you allowed to use it.
Keep in mind that generally the same code is generated whether the assignment occurs inside the conditional or outside - it's simply a shortcut to reduce the number of lines of code. There are always exceptions to the rule, but it never has to be in the conditional - you can always write your way out of that if you need to.
So another option is merely to disallow such statements, and where needed use the comments to turn off the LINT checking for this common error.
-Adam
I'd say that (i == 0) would sound more natural if you attempted to phrase a line in plain (and ambiguous) english. It really depends on the coding style of the programmer or the standards they are required to adhere to though.
Personally I don't like (1) and always do (2), however that reverses for readability when dealing with dialog boxes and other methods that can be extra long. It doesn't look bad how it is not, but if you expand out the MessageBox to it's full length. You have to scroll all the way right to figure out what kind of result you are returning.
So while I agree with your assertions of the simplistic comparison of value types, I don't necessarily think it should be the rule for things like message boxes.
both are equal, though i would prefer the 0==i variant slightly.
when comparing strings, it is more error-prone to compare "MyString".equals(getDynamicString())
since, getDynamicString() might return null.
to be more conststent, write 0==i
Well, it depends on the language and the compiler in question. Context is everything.
In Java and C#, the "assignment instead of comparison" typo ends up with invalid code apart from the very rare situation where you're comparing two Boolean values.
I can understand why one might want to use the "safe" form in C/C++ - but frankly, most C/C++ compilers will warn you if you make the typo anyway. If you're using a compiler which doesn't, you should ask yourself why :)
The second form (variable then constant) is more readable in my view - so anywhere that it's definitely not going to cause a problem, I use it.
Rule 0 for all coding standards should be "write code that can be read easily by another human." For that reason I go with (most-rapidly-changing value) test-against (less-rapidly-changing-value, or constant), i.e "i == 0" in this case.
Even where this technique is useful, the rule should be "avoid putting an lvalue on the left of the comparison", rather than the "always put any constant on the left", which is how it's usually interpreted - for example, there is nothing to be gained from writing
if (DateClass.SATURDAY == dateObject.getDayOfWeek())
if getDayOfWeek() is returning a constant (and therefore not an lvalue) anyway!
I'm lucky (in this respect, at least) in that these days in that I'm mostly coding in Java and, as has been mentioned, if (someInt = 0) won't compile.
The caveat about comparing two booleans is a bit of a red-herring, as most of the time you're either comparing two boolean variables (in which case swapping them round doesn't help) or testing whether a flag is set, and woe-betide-you if I catch you comparing anything explicitly with true or false in your conditionals! Grrrr!
In C, yes, but you should already have turned on all warnings and be compiling warning-free, and many C compilers will help you avoid the problem.
I rarely see much benefit from a readability POV.
Code readability is one of the most important things for code larger than a few hundred lines, and definitely i == 0 reads much easier than the reverse
Maybe not an answer to your question.
I try to use === (checking for identical) instead of equality. This way no type conversion is done and it forces the programmer do make sure the right type is passed,
You are right that placing the important component first helps readability, as readers tend to browse the left column primarily, and putting important information there helps ensure it will be noticed.
However, never talk down to a co-worker, and implying that would be your action even in jest will not get you high marks here.
I always go with the second method. In C#, writing
if (i = 0) {
}
results in a compiler error (cannot convert int to bool) anyway, so that you could make a mistake is not actually an issue. If you test a bool, the compiler is still issuing a warning and you shouldn't compare a bool to true or false. Now you know why.
I personally prefer the use of variable-operand-value format in part because I have been using it so long that it feels "natural" and in part because it seems to the predominate convention. There are some languages that make use of assignment statements such as the following:
:1 -> x
So in the context of those languages it can become quite confusing to see the following even if it is valid:
:if(1=x)
So that is something to consider as well. I do agree with the message box response being one scenario where using a value-operand-variable format works better from a readability stand point, but if you are looking for constancy then you should forgo its use.
This is one of my biggest pet peeves. There is no reason to decrease code readability (if (0 == i), what? how can the value of 0 change?) to catch something that any C compiler written in the last twenty years can catch automatically.
Yes, I know, most C and C++ compilers don't turn this on by default. Look up the proper switch to turn it on. There is no excuse for not knowing your tools.
It really gets on my nerves when I see it creeping into other languages (C#,Python) which would normally flag it anyway!
I believe the only factor to ever force one over the other is if the tool chain does not provide warnings to catch assignments in expressions. My preference as a developer is irrelevant. An expression is better served by presenting business logic clearly. If (0 == i) is more suitable than (i == 0) I will choose it. If not I will choose the other.
Many constants in expressions are represented by symbolic names. Some style guides also limit the parts of speech that can be used for identifiers. I use these as a guide to help shape how the expression reads. If the resulting expression reads loosely like pseudo code then I'm usually satisfied. I just let the expression express itself and If I'm wrong it'll usually get caught in a peer review.
We might go on and on about how good our IDEs have gotten, but I'm still shocked by the number of people who turn the warning levels on their IDE down.
Hence, for me, it's always better to ask people to use (0 == i), as you never know, which programmer is doing what.
It's better to be "safe than sorry"
if(DialogResult.OK == MessageBox.Show("Message")) ...
I would always recommend writing the comparison this way. If the result of MessageBox.Show("Message") can possibly be null, then you risk a NPE/NRE if the comparison is the other way around.
Mathematical and logical operations aren't reflexive in a world that includes NULLs.

if(false==condition). Why? [duplicate]

This question already has answers here:
What is the difference between these (bCondition == NULL) and (NULL==bCondition)? [duplicate]
(6 answers)
Closed 9 years ago.
I have received code from someone working earlier on it, and it contains a lot of lines like
while(false==find && false == err && k<kmax)
if(true==refract(ep1,ep2,n1,RI_blood, RI_collagen))
and my favorite line is
if(false == (ret_s<0))
The other code is done really well, documented just fine, but these lines with these odd conditions are throwing me off, and I wonder why they are done that way.
Especially that false==(ret_s<0) is completely confusing, and you kind of need to read that line like three times to understand what they want there.
Is this a common programming style, don't I understand the reasoning for that, or is that just bad style?
Edit: I don't feel this is similar to if(object==NULL) vs if(NULL==object), since this isn't about accidental assigning but about obfuscated if clauses...
Is this a common programming style?
No.
don't I understand the reasoning for that?
Some people like to explicitly compare booleans with true or false, even though the result is exactly the same boolean value. The logic is presumably that, by making the code harder to read and more surprising, people will think harder about it and make fewer assumptions about its behaviour. Or perhaps just that code should be hard to maintain, since it was hard to write.
Others like to write comparisons with constants backwards, which prevents mistakes like if (x = 5) when you meant if (x == 5). Any modern compiler will warn you about this mistake, so again its only real purpose is to make the code harder to read.
Combining these two behaviours gives the bizarre code you posted.
Or is that just bad style?
It's a style. I'm no judge of style, but if you like to keep maintainence programmers on their toes, it certainly does that. Personally, I like my code to be readable, but that's just me.
my favorite line is
I once encountered return a && !b implemented in about ten lines of code. The first line was switch(a).
Yoda Conditions
Using if(constant == variable) instead of if(variable == constant), like if(4 == foo). Because it's like saying "if blue is the sky" or "if tall is the man".
Its a safe guard against assignment in C++.
In C++ it is perfectly legal to do this
if (foo = true) ....
In this case the single = is an assignment and would replace the value of foo.
This is not legal and will generate a compiler error
if (true = foo) ....
Constants and literals are often put on the left because it prevents accidental assignments. Consider typing:
if(foo == bar)
as:
if(foo = bar)
The second might appear to work... but silently clobber foo. If foo is a constant, this error is not longer possible.
It's a self-protection technique that prevents you from accidentally typing an assignment operator (=) instead of equality operator (==), which can introduce strange bugs. Putting the constant value on the left hand side will introduce a compiler error, while putting a variable on the LHS will just silently compile.
Perhaps the original programmer thought that explicit comparison to true or false was clearler than if(condition) or if(!condition) and coded things in that way. I haven't seen this particular style before however.
It's quite subjective but I find while(!find && !err && k<kmax) easier to read.
The code could have been written for a shop where there is a site standard that every conditional statement must include a comparison operator, in order to avoid accidentally leaving out part of the comparison. (Maybe that's a stretch, but you did say that the rest of the code was very good.) That, coupled with a standard or habit of putting the constant on the left to avoid accidentally using = instead of == would give pretty much the code you showed. It doesn't explain the use of 'false' instead of the more natural 'true', though. Maybe it's a (misguided on multiple levels) attempt to gain microefficiency by comparing to zero instead of 1 at the machine level.
for my is only bad style,
if(false == (ret_s<0))
is equals to in C#
if(!(ret_s<0))

What are the advantages of squashing assignment and error checking in one line?

This question is inspired by this question, which features the following code snippet.
int s;
if((s = foo()) == ERROR)
print_error();
I find this style hard to read and prone to error (as the original question demonstrates -- it was prompted by missing parentheses around the assignment). I would instead write the following, which is actually shorter in terms of characters.
int s = foo();
if(s == ERROR)
print_error();
This is not the first time I've seen this idiom though, and I'm guessing there are reasons (perhaps historical) for it being so often used. What are those reasons?
I think it's for hysterical reasons, that early compilers were not so smart at optimizing. By putting it on one line as a single expression, it gives the compiler a hint that the same value fetched from foo() can be tested rather than specifically loading the value from s.
I prefer the clarity of your second example, with the assignment and test done later. A modern compiler will have no trouble optimizing this into registers, avoiding unnecessary loads from memory store.
When you are writing a loop, it is sometimes desirable to use the first form, as in this famous example from K&R:
int c;
while ((c = getchar()) != EOF) {
/* stuff */
}
There is no elegant "second-form" way of writing this without a repetition:
int c = getchar();
while (c != EOF) {
/* stuff */
c = getchar();
}
Or:
int c;
for (c = getchar(); c != EOF; c = getchar()) {
/* stuff */
}
Now that the assignment to c is repeated, the code is more error-prone, because one has to keep both the statements in sync.
So one has to be able to learn to read and write the first form easily. And given that, it seems logical to use the same form in if conditions as well.
I tend to use the first form mostly because I find it easy to read—as someone else said, it couples the function call and the return value test much more closely.
I make a conscious attempt at combining the two whenever possible. The "penalty" in size isn't enough to overcome the advantage in clarity, IMO.
The advantage in clarity comes from one fact: for a function like this, you should always think of calling the function and testing the return value as a single action that cannot be broken into two parts ("atomic", if you will). You should never call such a function without immediately testing its return value.
Separating the two (at all) leads to a much greater likelihood that you'll sometimes skip checking the return value completely. Other times, you'll accidentally insert some code between the call and the test of the return value that actually depends on that function having succeeded. If you always combine it all into a single statement, it (nearly) eliminates any possibility of falling into these traps.
I would always go for the second. It's easier to read, there's no danger of omitting the parentheses around the assignment and it is easier to step through with a debugger.
I often find the separation of the assignment out into a different line makes debugger watch or "locals" windows behave better vis-a-vis the presence and correct value of "s", at least in non-optimized builds.
It also allows the use of step-over separately on the assignment and test lines (again, in non-optimized builds), which can be helpful if you don't want to go mucking around in disassembly or mixed view.
YMMV per compiler and debugger and for optimized builds, of course.
I personally prefer for assignments and tests to be on different lines. It is less syntactically complicated, less error prone, and more easily understood. It also allows the compiler to give you more precise error/warning locations and often makes debugging easier.
It also allows me to more easily do things like:
int rc = function();
DEBUG_PRINT(rc);
if (rc == ERROR) {
recover_from_error();
} else {
keep_on_going(rc);
}
I prefer this style so much that in the case of loops I would rather:
while (1) {
int rc = function();
if (rc == ERROR) {
break;
}
keep_on_going(rc);
}
than do the assignment in the while conditional. I really don't like for my tests to have side-effects.
I often prefer the first form. I couldn't say exactly why, but it has something to do with the semantic involved.
The second style feels to me more like 2 separate operations. Call the function and then do something with the result, 2 different things. In the first style it's one logical unit. Call the function, save the temprary result and eventually handle the error case.
I know it's pretty vague and far from being completely rational, so I will use one or the other depending on the importance of the saved variable or the test case.
I believe that clarity should always prime over optimizations or "simplifications" based only on the amount of characters typed. This belief has stopped me from making many silly mistakes.
Separating the assignement and the comparison makes both clearer and so less error-prone, even if the duplication of the comparison might introduce a mistake once in a while. Among other things, parentheses become quickly hard to distinguish and keeping everything on one line introduces more parentheses. Also, splitting it up limits statements to doing only one of either fetching a value or assigning one.
However, if you expect people who will read your code to be more comfortable using the one-line idiom, then it is wide-spread enough not to cause any problems for most programmers. C programmers will definately be aware of it, even those that might find it awkward.

"Number line" style of comparisons

I recently read in Code Complete that the recommended way of handling expressions that involve numbers is to order them like a number line.
The book has 2 examples:
if ( (MIN_ELEMENTS <= i) && (i <= MAX_ELEMENTS) )
if ( (i < MIN_ELEMENTS) || (MAX_ELEMENTS < i ) )
With the first example showing that i is between the min and max elements, and the second example being that i falls outside the range between the elements.
I've been trying to adopt it, and I'm not sure if it's just the way I think, but I don't think it's making code any clearer.
Example:
if (m_Health > BOSS_HALF_HEALTH) // The way it was
if (BOSS_HALF_HEALTH <= m_Health) // The "number line" method
Is it just me, or does the number line method seem less clear? What are your thoughts regarding this practice?
It's also odd that he mentions putting constants on the left side of comparisons contradicts the number-line-method, but here it seems that the number line method leads to putting the constant on the left side.
I think the original motivation comes from having more than one comparison in the same logical expression. Both the quoted examples are comparing between both a lower and upper bound of a range. This ordering method may have value in those situations.
However, I don't think it's necessarily applicable if you're testing a single condition, such as m_Health > BOSS_HALF_HEALTH. In that case, the comparison you're making is whether something (a variable) is greater than something else. That's perfectly logical and doesn't need to be ordered in any particular way.
If you always ordered your comparisons in a "number line" way, you would never even need the > or >= comparison operators. They exist for good reasons.
I think it should be written the way you expect to read it.
Thus I would do:
if (i > MIN_ELEMENTS &&
i <= MAX_ELEMENTS)
instead of:
if ( (MIN_ELEMENTS <= i) && (i <= MAX_ELEMENTS) )
Because I read C alike english, like
if i is less than min and more than max
instead of
if min is less than is and is is less than max
because I care about i, not min.
I think this is not a method that is inherently superior. The advantage comes in having the expressions the same way throughout the code, making the code faster to read when you're used to it.
Steve McConnell's work is superb but there are little things I don't agree with him on. This may be one of those things with you.
If you feel it's making your code less clear, then don't do it just because Steve McConnell thinks it's the way to go.
I guess the original intention is to just make a habit.
Language is just a familiar arrangement of words. Once it becomes a habit,
you get accustomed to it.
If you can train your brain to read:
if ( CONST == i ) //[1]
in the same way as:
if ( i == CONST) //[2]
you will never fall prey to the bug of:
if ( i = CONST) //[3]
However, it should be noted that most modern compilers today give a warning on construct [3]
In conclusion, if you are fix all your compiler warnings, you can use either of the coding style.

Why Switch/Case and not If/Else If?

This question in mainly pointed at C/C++, but I guess other languages are relevant as well.
I can't understand why is switch/case still being used instead of if/else if. It seems to me much like using goto's, and results in the same sort of messy code, while the same results could be acheived with if/else if's in a much more organized manner.
Still, I see these blocks around quite often. A common place to find them is near a message-loop (WndProc...), whereas these are among the places when they raise the heaviest havoc: variables are shared along the entire block, even when not propriate (and can't be initialized inside it). Extra attention has to be put on not dropping break's, and so on...
Personally, I avoid using them, and I wonder wether I'm missing something?
Are they more efficient than if/else's?
Are they carried on by tradition?
Summarising my initial post and comments - there are several advantages of switch statement over if/else statement:
Cleaner code. Code with multiple chained if/else if ... looks messy and is difficult to maintain - switch gives cleaner structure.
Performance. For dense case values compiler generates jump table, for sparse - binary search or series of if/else, so in worst case switch is as fast as if/else, but typically faster. Although some compilers can similarly optimise if/else.
Test order doesn't matter. To speed up series of if/else tests one needs to put more likely cases first. With switch/case programmer doesn't need to think about this.
Default can be anywhere. With if/else default case must be at the very end - after last else. In switch - default can be anywhere, wherever programmer finds it more appropriate.
Common code. If you need to execute common code for several cases, you may omit break and the execution will "fall through" - something you cannot achieve with if/else. (There is a good practice to place a special comment /* FALLTHROUGH */ for such cases - lint recognises it and doesn't complain, without this comment it does complain as it is common error to forgot break).
Thanks to all commenters.
Well, one reason is clarity....
if you have a switch/case, then the expression can't change....
i.e.
switch (foo[bar][baz]) {
case 'a':
...
break;
case 'b':
...
break;
}
whereas with if/else, if you write by mistake (or intent):
if (foo[bar][baz] == 'a') {
....
}
else if (foo[bar][baz+1] == 'b') {
....
}
people reading your code will wonder "were the foo expressions supposed to be the same", or "why are they different"?
please remember that case/select provides additional flexibility:
condition is evaluated once
is flexible enough to build things like the Duff's device
fallthrough (aka case without break)
as well as it executes much faster (via jump/lookup table) * historically
Also remember that switch statements allows the flow of control to continue, which allows you to nicely combine conditions while allowing you to add additional code for certain conditions, such as in the following piece of code:
switch (dayOfWeek)
{
case MONDAY:
garfieldUnhappy = true;
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
case FRIDAY:
weekDay = true;
break;
case SATURDAY:
weekendJustStarted = true;
case SUNDAY:
weekendDay = true;
break;
}
Using if/else statements here instead would not be anywhere as nice.
if (dayOfWeek == MONDAY)
{
garfieldUnhappy = true;
}
if (dayOfWeek == SATURDAY)
{
weekendJustStarted = true;
}
if (dayOfWeek == MONDAY || dayOfWeek == TUESDAY || dayOfWeek == WEDNESDAY
|| dayOfWeek == THURSDAY || dayOfWeek == FRIDAY)
{
weekDay = true;
}
else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY)
{
weekendDay = true;
}
If there are lots of cases, the switch statement seems cleaner.
It's also nice when you have multiple values for which you want the same behavior - just using multiple "case" statements that fall through to a single implementation is much easier to read than a if( this || that || someotherthing || ... )
It might also depend on your language -- For example, some languages switch only works with numeric types, so it saves you some typing when you're working with an enumerated value, numeric constants... etc...
If (day == DAYOFWEEK_MONDAY) {
//...
}
else if (day == DAYOFWEEK_TUESDAY) {
//...
}
//etc...
Or slightly easier to read...
switch (day) {
case DAYOFWEEK_MONDAY :
//...
case DAYOFWEEK_TUESDAY :
//...
//etc...
}
Switch/case is usually optimized more efficiently than if/else if/else, but is occasionally (depending on language and compiler) translated to simple if/else if/else statements.
I personally think switch statements makes code more readable than a bunch of if statements; provided that you follow a few simple rules. Rules you should probably follow even for your if/else if/else situations, but that's again my opinion.
Those rules:
Never, ever, have more than one line on your switch block. Call a method or function and do your work there.
Always check for break/ case fallthrough.
Bubble up exceptions.
Clarity. As I said here, a clue that else if is problematic is
the frequency with which ELSE IF is
used in a far more constrained way
than is allowed by the syntax. It is a
sledgehammer of flexibility,
permitting entirely unrelated
conditions to be tested. But it is
routinely used to swat the flies of
CASE, comparing the same expression
with alternate values...
This reduces the readability of the
code. Since the structure permits a
universe of conditional complexity,
the reader needs to keep more
possibilities in mind when parsing
ELSE IF than when parsing CASE.
Actually a switch statement implies that you are working off of something that is more or less an enum which gives you an instant clue what's going on.
That said, a switch on an enum in any OO language could probably be coded better--and a series of if/else's on the same "enum" style value would be at least as bad and even worse at conveying meaning.
addressing the concern that everything inside the switch has equivalent scope, you can always throw your case logic into another { } block, like so ..
switch( thing ) {
case ONETHING: {
int x; // local to the case!
...
}
break;
case ANOTHERTHING: {
int x; // a different x than the other one
}
break;
}
.. now I'm not saying that's pretty. Just putting it out there as something that's possible if you absolutely have to isolate something in one case from another.
one other thought on the scope issue - it seems like a good practice to only put one switch inside a function, and not a lot else. Under those circumstances, variable scope isn't as much of a concern, since that way you're generally only dealing with one case of execution on any given invocation of the function.
ok, one last thought on switches: if a function contains more than a couple of switches, it's probably time to refactor your code. If a function contains nested switches, it's probably a clue to rethink your design a bit =)
switch case is mainly used to have the choice to made in the programming .This is not related the conditional statement as :
if your program only require the choice to make then why you use the if/else block and increase the programming effort plus it reduce the execution speed of the program .
Switch statements can be optimized for speed, but can take up more memory if the case values are spread out over large numbers of values.
if/else are generally slow, as each value needs to be checked.
A Smalltalker might reject both switch and if-then-else's and might write something like:-
shortToLongDaysMap := Dictionary new.
shortToLongDaysMap
at: 'Mon' put: 'Monday';
at: 'Tue' put: 'Tuesday';
at: 'Wed' put: 'Wednesday'
etc etc.
longForm := shortToLongDaysMap at: shortForm ifAbsent: [shortForm]
This is a trivial example but I hope you can see how this technique scales for large numbers of cases.
Note the second argument to at:IfAbsent: is similar to the default clause of a case statement.
The main reason behind this is Maintainability and readability. Its easy to make code more readable and maintainable with Switch/case statement then if/else. Because you have many if/else then code become so much messy like nest and its very hard to maintain it.
And some how execution time is another reason.
Pretty sure they compile to the same things as if/else if, but I find the switch/case easier to read when there are more than 2 or 3 elses.