if else Style
-
Greetings & Kind Regards I seek advice and knowledge of others' practice re/ a minor matter of style. In particular to be specific I vacillate betwixt and between two forms of final statement of if ... else ... series of statements assuming every possible condition is accounted for as shown in simple specimen / example / sample below (not snippet as it is not a snip of a larger code base). 1st style : if(expression == true) {...} else {...} 2nd style : if(expression == true) {...} else if(expression == false) {...} Note it is the final statement I am inquiring regards. Do your kind selves accept the default final result as shown in 1st style or perform explicit unnecessary test as shown in 2nd style for no other reason than to make the code self documenting and easier to understand in particular for a complex lengthy series of conditions. btw in 2nd style on occasion I add as final statement else throw who_the_heck_knows_what_happened; Thank You Kindly [edit] I have concluded kind Jacquers is quite correct. As it happened upon some coding just now of a simple series of such it was evident an explicit final test results in confusion as it is clearly not necessary. However in a lengthy complex series an explicit test makes code self documenting and so simpler to understand. KISS
In reading all of the responses, I'm quite surprised that the only alternative mentioned was the tertiary operator (?: ). While it's simple to respond 'context dependent' as I saw in some of the replies, I think maybe it would help to spell out the concerns as well as offer up more choices. Let's start with the elephant in the room... readability and maintainability. They both go hand in hand to answer the question "what are you trying to do or say in the code?" In addition, some of the choices can lead to both bugs and code creep. Let's start with if/else as a potential solution to express a/the logical path to traverse. A couple of simple rules would help (these are *my* rules, some may be obvious, but some are what I call 'Where's the curly brace' religious preferences. Take everything I write here are my own style rather than engage in religiosity).
if (condition 1)
{
// do something 1
}
else if (condition 2)
{
// do something 2
}
else
{
// do something 3
}I always include the curly braces to ensure that scope is honored i.e. what code is executed based on which condition is met. Too often I've see this:
if (condition 1)
// do something 1
else if (condition 2)
// do something 2
else
// do something 3The problem here is if another author comes in to add/maintain the code, and adds a second line of execution to one of the conditions. If that author forgets to now add the curly braces to enclose scope, bad things happen.
if (condition 1)
// do something 1
else if (condition 2)
// do something 2A
// do something 2B <-- we've exited the scope of the if/else clause. Ooops!
else
// do something 3In addition, the whole Nickleback induced hatred the tertiary operator hails back to a late 70's bug introduced in a version (or couple of versions) of the Whitesmiths C compiler, and has since become lore. If we are striving for readability, then:
if (condition) ? "do one thing" : "do the other thing";
If you are vehemently opposed to this, chances are you also avoid the null coalescing as well as other similar constructs:
char *s = null;
char *t = null;
...t = s ? "some string" : "some default";
But really, is this the only way to proceed? How about:
switch (operand)
{
case 1:
// do something case 1
break;
case 2:
// do something case 2
break;
case 3:
// do something case 3 -
In reading all of the responses, I'm quite surprised that the only alternative mentioned was the tertiary operator (?: ). While it's simple to respond 'context dependent' as I saw in some of the replies, I think maybe it would help to spell out the concerns as well as offer up more choices. Let's start with the elephant in the room... readability and maintainability. They both go hand in hand to answer the question "what are you trying to do or say in the code?" In addition, some of the choices can lead to both bugs and code creep. Let's start with if/else as a potential solution to express a/the logical path to traverse. A couple of simple rules would help (these are *my* rules, some may be obvious, but some are what I call 'Where's the curly brace' religious preferences. Take everything I write here are my own style rather than engage in religiosity).
if (condition 1)
{
// do something 1
}
else if (condition 2)
{
// do something 2
}
else
{
// do something 3
}I always include the curly braces to ensure that scope is honored i.e. what code is executed based on which condition is met. Too often I've see this:
if (condition 1)
// do something 1
else if (condition 2)
// do something 2
else
// do something 3The problem here is if another author comes in to add/maintain the code, and adds a second line of execution to one of the conditions. If that author forgets to now add the curly braces to enclose scope, bad things happen.
if (condition 1)
// do something 1
else if (condition 2)
// do something 2A
// do something 2B <-- we've exited the scope of the if/else clause. Ooops!
else
// do something 3In addition, the whole Nickleback induced hatred the tertiary operator hails back to a late 70's bug introduced in a version (or couple of versions) of the Whitesmiths C compiler, and has since become lore. If we are striving for readability, then:
if (condition) ? "do one thing" : "do the other thing";
If you are vehemently opposed to this, chances are you also avoid the null coalescing as well as other similar constructs:
char *s = null;
char *t = null;
...t = s ? "some string" : "some default";
But really, is this the only way to proceed? How about:
switch (operand)
{
case 1:
// do something case 1
break;
case 2:
// do something case 2
break;
case 3:
// do something case 3 -
Stacy Dudovitz wrote:
If that author forgets to now add the curly braces to enclose scope, bad things happen.
So not only coding now to guess at the competence of future programmers but also presuming that comprehensive unit testing will not happen?
To the first question about competence, that may be a bit harsh. We are, after all, human beings, and as such, even the best of us make mistakes. To be clear, while some mistakes can be attributed to competency levels and/or experience, I've also seen errors due to time pressure from the decisions makers, long hours of debugging a nasty problem, or other factors which can contribute to bugs. Hence, my suggestion/recommendation falls more in line with defensive coding rather than assuming that everyone that is not me is an idiot. Your mileage may vary on that point. With regards to unit testing, even in shops where unit testing is mandated as part of the development process (again, until a time deadline or other external factors discourage the practice in light of external pressures), my experience has been that often unit testing is more to tick off a checkbox than to actually produce maintainable and reliable code. Writing proper unit test code is an artform unto itself, and is predicated on other practices such as one method should encompass exactly one function. (Lets not split hairs on the triumvirate of the types of testing i.e. unit, system and integration tests. In this case I am referring to all three under the single banner of 'unit testing'.) Bottom line, whatever practice you or your shop choose to implement, it should be purposeful and consistent. My post here was to offer a more thorough response to the original question.
-
Greetings & Kind Regards I seek advice and knowledge of others' practice re/ a minor matter of style. In particular to be specific I vacillate betwixt and between two forms of final statement of if ... else ... series of statements assuming every possible condition is accounted for as shown in simple specimen / example / sample below (not snippet as it is not a snip of a larger code base). 1st style : if(expression == true) {...} else {...} 2nd style : if(expression == true) {...} else if(expression == false) {...} Note it is the final statement I am inquiring regards. Do your kind selves accept the default final result as shown in 1st style or perform explicit unnecessary test as shown in 2nd style for no other reason than to make the code self documenting and easier to understand in particular for a complex lengthy series of conditions. btw in 2nd style on occasion I add as final statement else throw who_the_heck_knows_what_happened; Thank You Kindly [edit] I have concluded kind Jacquers is quite correct. As it happened upon some coding just now of a simple series of such it was evident an explicit final test results in confusion as it is clearly not necessary. However in a lengthy complex series an explicit test makes code self documenting and so simpler to understand. KISS
-
Do not attempt the extra check if you are dealing with floating points. You might really need the extra ELSE clause. if (x > 1.0) { } else if (x <= 1.0) { } else { // yes you can reach this throw wtf; } What are possible values of x?
Disagree! (contingent on compiler switches set, of course :) )
else {
// yes you can reach this
throw wtf;
}if (x == NaN) or some similar hairy answer, the compiler (again, with the correct compilation switches set) will automagically throw an exception. Sidebar: One would NOT want to set said same switches on an embedded piece of code, since typically exception handling is turned off. Therefore, one would NOT, in such an instance wish to
throw wtf
. -
BernardIE5317 wrote:
if(expression == true) {...}
I had forgotten another variance on mandating usage.
if(true == expression)
Some C++ coders insisted on that because, the possibility existed that one might code the following.
if(expression = true)
And that is valid in C++. Myself C++ programmers not controlling the scope of the their memory allocations was always, and still is, much more of a significant problem.
jschell wrote:
if(true == expression)
sometimes referred to as Yoda formatting.
-
To the first question about competence, that may be a bit harsh. We are, after all, human beings, and as such, even the best of us make mistakes. To be clear, while some mistakes can be attributed to competency levels and/or experience, I've also seen errors due to time pressure from the decisions makers, long hours of debugging a nasty problem, or other factors which can contribute to bugs. Hence, my suggestion/recommendation falls more in line with defensive coding rather than assuming that everyone that is not me is an idiot. Your mileage may vary on that point. With regards to unit testing, even in shops where unit testing is mandated as part of the development process (again, until a time deadline or other external factors discourage the practice in light of external pressures), my experience has been that often unit testing is more to tick off a checkbox than to actually produce maintainable and reliable code. Writing proper unit test code is an artform unto itself, and is predicated on other practices such as one method should encompass exactly one function. (Lets not split hairs on the triumvirate of the types of testing i.e. unit, system and integration tests. In this case I am referring to all three under the single banner of 'unit testing'.) Bottom line, whatever practice you or your shop choose to implement, it should be purposeful and consistent. My post here was to offer a more thorough response to the original question.
-
Disagree! (contingent on compiler switches set, of course :) )
else {
// yes you can reach this
throw wtf;
}if (x == NaN) or some similar hairy answer, the compiler (again, with the correct compilation switches set) will automagically throw an exception. Sidebar: One would NOT want to set said same switches on an embedded piece of code, since typically exception handling is turned off. Therefore, one would NOT, in such an instance wish to
throw wtf
.The OP never mentioned language or compilers. Some compilers for whatever language may not support those options. It was a general stylistic question. Most compilers (and forums) won’t even warn when you use assignment operator instead of comparison operator. 😊
-
In reading all of the responses, I'm quite surprised that the only alternative mentioned was the tertiary operator (?: ). While it's simple to respond 'context dependent' as I saw in some of the replies, I think maybe it would help to spell out the concerns as well as offer up more choices. Let's start with the elephant in the room... readability and maintainability. They both go hand in hand to answer the question "what are you trying to do or say in the code?" In addition, some of the choices can lead to both bugs and code creep. Let's start with if/else as a potential solution to express a/the logical path to traverse. A couple of simple rules would help (these are *my* rules, some may be obvious, but some are what I call 'Where's the curly brace' religious preferences. Take everything I write here are my own style rather than engage in religiosity).
if (condition 1)
{
// do something 1
}
else if (condition 2)
{
// do something 2
}
else
{
// do something 3
}I always include the curly braces to ensure that scope is honored i.e. what code is executed based on which condition is met. Too often I've see this:
if (condition 1)
// do something 1
else if (condition 2)
// do something 2
else
// do something 3The problem here is if another author comes in to add/maintain the code, and adds a second line of execution to one of the conditions. If that author forgets to now add the curly braces to enclose scope, bad things happen.
if (condition 1)
// do something 1
else if (condition 2)
// do something 2A
// do something 2B <-- we've exited the scope of the if/else clause. Ooops!
else
// do something 3In addition, the whole Nickleback induced hatred the tertiary operator hails back to a late 70's bug introduced in a version (or couple of versions) of the Whitesmiths C compiler, and has since become lore. If we are striving for readability, then:
if (condition) ? "do one thing" : "do the other thing";
If you are vehemently opposed to this, chances are you also avoid the null coalescing as well as other similar constructs:
char *s = null;
char *t = null;
...t = s ? "some string" : "some default";
But really, is this the only way to proceed? How about:
switch (operand)
{
case 1:
// do something case 1
break;
case 2:
// do something case 2
break;
case 3:
// do something case 3 -
Greetings & Kind Regards I seek advice and knowledge of others' practice re/ a minor matter of style. In particular to be specific I vacillate betwixt and between two forms of final statement of if ... else ... series of statements assuming every possible condition is accounted for as shown in simple specimen / example / sample below (not snippet as it is not a snip of a larger code base). 1st style : if(expression == true) {...} else {...} 2nd style : if(expression == true) {...} else if(expression == false) {...} Note it is the final statement I am inquiring regards. Do your kind selves accept the default final result as shown in 1st style or perform explicit unnecessary test as shown in 2nd style for no other reason than to make the code self documenting and easier to understand in particular for a complex lengthy series of conditions. btw in 2nd style on occasion I add as final statement else throw who_the_heck_knows_what_happened; Thank You Kindly [edit] I have concluded kind Jacquers is quite correct. As it happened upon some coding just now of a simple series of such it was evident an explicit final test results in confusion as it is clearly not necessary. However in a lengthy complex series an explicit test makes code self documenting and so simpler to understand. KISS
Hell no! If you must put the second conditional for documentation purposes, make it a comment if (cond) ... else // if (!cond) ... or if (cond) ... else // cond ... I've seen that style used for conditional compilation, not so much for braces. #if cond ... #else ... #endif //cond