Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
In the below 2 ways, which method one has to prefer. I personally comfortable with method 2, the if-elseladder one. But my friend told, they invoke redundancy in coding., and he used to achieve that in many single if statements, like..
Examples:
if( cond1 && cond2 ){}
if(cond1 && cond3){}
if(cond3 && cond2){} etc..
Instead of.,
if(cond1)
{
}
else
{
if(cond3 && cond2)
{}
}
//Way 1
String str = cond1 && !cond2 && !cond3 ? "world" : "hello" ;
(cond1,cond2,cond3 -> aren't simple checks. say they itself contains many || and &&'s )
//Way 2
String str;
if (cond1)
{
if (cond2)
{
str = "hello";
}
else
{
if (cond3)
{
str = "hello";
}
else
{
str = "world";
}
}
}
String str;
if (cond1 && cond2) {
str = "hello";
} else if(cond1 && cond3) {
str = "hello";
} else if(cond1) {
str = "world";
}
This method is a bit inbetween the two. I am not a fan of the first method at all. But personally, this method seems a bit more clear than your second method and more readable, and it does the same thing.
This isn't to suggest that you should avoid nesting if statements. I'm merely suggesting that you should feel free to use compound if statements also. In my opinion, the contents of an if else block should be more than just more nested if or if else. If there is nothing inside your if block that's not in a nested if block, then your statement can be rewritten with compound if statements.
There's an alternate to my first method also.
String str;
if(cond1) {
if(cond2) {
//do stuff
} else if(cond3) {
//do stuff
} else {
//do stuff
}
}
This will check cond1 just once. It still has a purely nested if that can be rewritten as compound, but if you're concerned about performance (if cond1 is a particularly time-consuming check), this will check cond1 just once, and it still more readable than what you offered in the question originally (in my opinion). This difference is more subtle.
There's also this method.
bool flag1 = cond1;
bool flag2 = cond2;
bool flag3 = cond3;
String str;
if (flag1 && flag2) {
str = "hello";
} else if(flag1 && flag3) {
str = "hello";
} else if(flag1) {
str = "world";
}
In this method, you can make simple and short compound condition statements by using bool variables as flags. You can check any of the conditions as many times as you want (any time the condition may change, you need to flag1 = cond1 again, etc), without doing all the computing it may take to actually check the condition. You just check it once and save the result of the condition.
I have seen many different types of coding styles and from all that I have found, it all depends on the situation. There is not a universal standard, other than do not write un-readable code.
Your colleagues may desire a specific stylistic pattern and thus you follow that one.
To a moderately experienced programmer both are very readable and readability is very important for code, especially if it is going to be maintained by somebody else(which is eventually inevitable).
It is all what your goals are. If you want large if/else statements, I am not sure there is an inherent reason not too, other than it may eventually make unreadable code, depending on how it is implemented.
Related
Missing equal sign inside assignment (typing = instead of ==) make unwanted assignment inside a condition statement.
For example, consider the scenario below (this example is in C, but the question is valid also for interpreted code).
CASE A:
int g=1;
if ( g == 3 )
{
printf("g is 3");
}
else
{
printf("g is not 3");
}
//this return: "g is not 3"
CASE B: (typo: missing = inside condition)
int g=1;
if ( g = 3 )
{
printf("g is 3");
}
else
{
printf("g is not 3");
}
//this return: "g is 3" because of the assignment
Both the cases are formally correct, so the code will work but not as we want; and may be hard to debug.
How to prevent this situation? There is a solution that cover the interpreted code (for example javascript), apart static analyzers?
The thing is, using an assignment inside a condition body for if, while, or for is perfectly valid C and is very often used intentionally. For example, I often find myself using the following skeleton code to create a window when writing a Win32 API GUI:
if((hWnd = CreateWindowExW(...)) == NULL)
{
MessageBoxW(NULL, L"Window creation failed", L"Error", MB_OK | MB_ICONSTOP);
return GetLastError();
}
If the test is solely for equality and you want to avoid using the = operator accidentally, one thing you can do is get into the habit of putting the r-value on the left side of the operator, so that if you accidentally use =, it will produce a compilation error:
char *p = malloc(100000);
if(NULL == p)
{
// handle null pointer
}
Obviously, this only works if at least one side of the comparison is an r-value or a const variable.
I'm working on a legacy app that is not just spaghetti, but turns to egg shells when broken (Humpty Dumpty syndrome), where figuring out what is going on as the code meanders around like a drunken sailor in Old Manila is like trying to find a poodle in a smokestack.
As an example, here is a method that I must grok; this is just the first part of it:
private void InitializeBackgroundThread( LoginStatuses loginStatus, string DialogCap )
{
try
{
double pause = 1;
int wait = 250;
ProgressChangedFlag = false;
ProgressChangedIndex = 0;
pc = new PendingCommands( pause, wait );
PendingCommands.ProcessCommands = true;
if (!((loginStatus == LoginStatuses.LoginVendors) || (loginStatus == LoginStatuses.LoginInventory)))
PendingCommands.Processing = false;
PendingCommands.Timeout = false;
Util.StopCancelRequested = false;
if( timeOut != "" )
pc.timeOut = timeOut;
if (!((loginStatus == LoginStatuses.LoginVendors) || (loginStatus == LoginStatuses.LoginInventory)))
{
InitializeBackgroundThread_CCRLoginTerminate (true);
InitializeBackgroundThread_CCRTimerExceeded (true);
InitializeBackgroundThread_CCROnline (true);
}
if (loginStatus == LoginStatuses.LoginVendors)
{
InitializeBackgroundThread_CCRCommandConfirmedGetsites (false);
InitializeBackgroundThread_CCRCommandConfirmed (false);
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (true);
}
else if (loginStatus == LoginStatuses.LoginSitesData)
{
InitializeBackgroundThread_CCRCommandConfirmed (false);
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (false);
InitializeBackgroundThread_CCRCommandConfirmedGetsites (true);
}
else
{
InitializeBackgroundThread_CCRCommandConfirmedSitesetup (false);
InitializeBackgroundThread_CCRCommandConfirmedGetsites (false);
InitializeBackgroundThread_CCRCommandConfirmed (true);
}
InitializeBackgroundThread_CCRProgress (true);
InitializeBackgroundThread_CCRProgressChanged (true);
InitializeBackgroundThread_CCRProgressComm (true);
Now I can "deskcheck" it by going through it with a notepad, asking myself, "Okay, what will happen - which variables will be assigned which values, and which methods will be called - if loginStatus is "AllQuiet"? What if loginStatus is "SNAFU"? Etc. etc. ad nauseum.
Wouldn't it be great if a tool could eat this spaghetti right up and spit out a report such as:
*With a loginStatus of "AllQuiet"
PendingCommands.Processing is set to true.
InitializeBackgroundThread_CCRProgressChanged is called.
...
With a loginStatus of "SNAFU"
(etc.)*
This would be a "killer" debugging/sanity check tool. I know there are code coverage tools, but are there any that are this sophisticated?
This isn't code coverage, which simply tracks what code gets executed if you run a specific test.
What you want is something like a cross between program slicing ("show me everything downstream/upstream from some code point" aka 'a slice' http://en.wikipedia.org/wiki/Program_slicing),
and partial evaluation ("show me what this code looks like if I assume some value is a specific constant" http://en.wikipedia.org/wiki/Partial_evaluation). And you want it to display the result superimposed on top of your actual code (e.g. boldface the selected part) to see your focus.
Yes, that would be wickedly nice tool.
No, I don't know of any. There are program slicers for C and C++ (See http://www.grammatech.com/research/technologies/codesurfer). I don't think they have the partial evaluation part, but I think they do have some other options to minimize the size the slice being inspected.
Okay, this is a simple question, but I'd like some oppinions on the correct practice here. I am not looking at this for performance concerns, because CPU's are so powerful that this wouldn't make any perceivable difference unless called without a looping contruct with thousands of iterations. I just want views on what is the accepted standard.
I have a method that bascially just does a check returns a boolean. However, there are numerous ways to implement this.
Here is how I would normally implement this.
public bool CanUndo()
{
if (_nCurrentUndoIndex > 0)
return true;
else
return false;
}
However, it is often frowned upon to return from the middle of a method. The only time I normally do this is when performing a check on a form submission like this.
if (String.IsNullOrEmpty(firstName.Text))
{
MessageBox.Show("Please enter a first name", "Incomplete");
return;
}
I consider that acceptable.
Back to the undo question, an alternative way to code it would be this.
public bool CanUndo()
{
bool returnVal;
if (_nCurrentUndoIndex > 0)
returnVal = true;
else
returnVal = false;
return returnVal;
}
This however unncessarily allocates a variable and is more verbose code. Another option would be.
public bool CanUndo()
{
bool returnVal = false;
if (_nCurrentUndoIndex > 0)
returnVal = true;
return returnVal;
}
This is more streamlined as it gets rid of the else. However, if the value is true is makes an unneccesary assignment by initializing it to false.
public bool CanUndo () {
return _nCurrentUndoIndex > 0;
}
Personally I don't have a problem with returning from the middle of a method. It complicates cleanup code for C functions but with RAII that argument disappears.
I prefer to exit as soon as is suitable otherwise you get
if (x) {
if (y) {
if (z) {
complete
}
}
}
rather than
if (!x)
return
if (!y)
return
if (!z)
return
complete
This way you avoid nesting, wide lines (horizontal screen space is expensive, vertical space is cheap) and you always know that if you're still in a function then you're not in an error path. Code which works well with this design also works well with exceptions, which is very important.
you should always contract boolean returns to their logical aquivalent, because this is much easier to read for developers, it is faster to write for you and it get contracted by the compiler anyways.
consider an expanded or:
if (a == 1)
return true;
else if (a == 2)
return true;
else if (a == 3)
return true;
else
return false;
and the reason should become obvious when you compare it to the contracted version
return (a == 1) || (a == 2) || (a == 3)
public bool CanUndo()
{
return (_nCurrentUndoIndex > 0);
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
My group is having some discussion and strong feelings about for loop construction.
I have favored loops like:
size_t x;
for (x = 0; x < LIMIT; ++x) {
if (something) {
break;
}
...
}
// If we found what we're looking for, process it.
if (x < LIMIT) {
...
}
But others seem to prefer a Boolean flag like:
size_t x;
bool found = false;
for (x = 0; x < LIMIT && !found; ++x) {
if (something) {
found = true;
}
else {
...
}
}
// If we found what we're looking for, process it.
if (found) {
...
}
(And, where the language allows, using "for (int x = 0; ...".)
The first style has one less variable to keep track of and a simpler loop header. Albeit at the cost of "overloading" the loop control variable and (some would complain), the use of break.
The second style has clearly defined roles for the variables but a more complex loop condition and loop body (either an else, or a continue after found is set, or a "if (!found)" in the balance of the loop).
I think that the first style wins on code complexity. I'm looking for opinions from a broader audience. Pointers to actual research on which is easier to read and maintain would be even better. "It doesn't matter, take it out of your standard" is a fine answer, too.
OTOH, this may be the wrong question. I'm beginning to think that the right rule is "if you have to break out of a for, it's really a while."
bool found = false;
x = 0;
while (!found && x < LIMIT) {
if (something) {
found = true;
...handle the thing...
}
else {
...
}
++x;
}
Does what the first two examples do but in fewer lines. It does divide the initialization, test, and increment of x across three lines, though.
I'd actually dare to suggest consideration of GOTO to break out of loops in such cases:
for (size_t x = 0; x < LIMIT && !found; ++x) {
if (something)
goto found;
else {
...
}
}
// not found
...
return;
found:
...
return;
I consider this form to be both succint and readable. It may do some good in many simple cases (say, when there is no common processing in this function, in both found/unfound cases).
And about the general frowning goto receives, I find it to be a common misinterpretation of Dijkstra's original claims: his arguments favoured structured loop clauses, as for or while, over a primitive loop-via-goto, that still had a lot of presence circa 1968. Even the almighty Knuth eventualy says -
The new morality that I propose may
perhaps be stated thus: "Certain go to
statements which arise in connection with
well-understood transformations are acceptable, provided that the program documentation explains what the transformation was."
Others here occasionaly think the same.
While I disagree that an extra else really makes the 2nd more complicated, I think it's primarily a matter of aesthetics and keeping to your standard.
Personally, I have a probably irrational dislike of breaks and continues, so I'm MUCH more likely to use the found variable.
Also, note that you CAN add the found variable to the 1st implementation and do
if(something)
{
found = true;
break;
}
if you want to avoid the variable overloading problem at the expense of the extra variable, but still want the simple loop terminator...
The former example duplicates the x < LIMIT condition, whereas the latter doesn't.
With the former, if you want to change that condition, you have to remember to do it in two places.
I would prefer a different one altogether:
for (int x = 0; x < LIMIT; ++x) {
if (something) {
// If we found what we're looking for, process it.
...
break;
}
...
}
It seems you have not any trouble you mention about one or the other... ;-)
no duplication of condition, or readability problem
no additional variable
I don't have any references to hand (-1! -1!), but I seem to recall that having multiple exit points (from a function, from a loop) has been shown to cause issues with maintainability (I used to know someone who wrote code for the UK military and it was Verboten to do so). But more importantly, as RichieHindle points out, having a duplicate condition is a Bad Thing, it cries out for introducing bugs by changing one and not the other.
If you weren't using the condition later, I wouldn't be bothered either way. Since you are, the second is the way to go.
This sort of argument has been fought out here before (probably many times) such as in this question.
There are those that will argue that purity of code is all-important and they'll complain bitterly that your first option doesn't have identical post-conditions for all cases.
What I would answer is "Twaddle!". I'm a pragmatist, not a purist. I'm as against too much spaghetti code as much as the next engineer but some of the hideous terminating conditions I've seen in for loops are far worse than using a couple of breaks within your loop.
I will always go for readability of code over "purity" simply because I have to maintain it.
This looks like a place for a while loop. For loops are Syntactic Sugar on top of a While loop anyway. The general rule is that if you have to break out of a For loop, then use a While loop instead.
package com.company;
import java.io.*;
import java.util.Scanner;
public class Main {
// "line.separator" is a system property that is a platform independent and it is one way
// of getting a newline from your environment.
private static String NEWLINE = System.getProperty("line.separator");
public static void main(String[] args) {
// write your code here
boolean itsdone = false;
String userInputFileName;
String FirstName = null;
String LastName = null;
String user_junk;
String userOutputFileName;
String outString;
int Age = -1;
int rint = 0;
int myMAX = 100;
int MyArr2[] = new int[myMAX];
int itemCount = 0;
double average = 0;
double total = 0;
boolean ageDone = false;
Scanner inScan = new Scanner(System.in);
System.out.println("Enter First Name");
FirstName = inScan.next();
System.out.println("Enter Last Name");
LastName = inScan.next();
ageDone = false;
while (!ageDone) {
System.out.println("Enter Your Age");
if (inScan.hasNextInt()) {
Age = inScan.nextInt();
System.out.println(FirstName + " " + LastName + " " + "is " + Age + " Years old");
ageDone = true;
} else {
System.out.println("Your Age Needs to Have an Integer Value... Enter an Integer Value");
user_junk = inScan.next();
ageDone = false;
}
}
try {
File outputFile = new File("firstOutFile.txt");
if (outputFile.createNewFile()){
System.out.println("firstOutFile.txt was created"); // if file was created
}
else {
System.out.println("firstOutFile.txt existed and is being overwritten."); // if file had already existed
}
// --------------------------------
// If the file creation of access permissions to write into it
// are incorrect the program throws an exception
//
if ((outputFile.isFile()|| outputFile.canWrite())){
BufferedWriter fileOut = new BufferedWriter(new FileWriter(outputFile));
fileOut.write("==================================================================");
fileOut.write(NEWLINE + NEWLINE +" You Information is..." + NEWLINE + NEWLINE);
fileOut.write(NEWLINE + FirstName + " " + LastName + " " + Age + NEWLINE);
fileOut.write("==================================================================");
fileOut.close();
}
else {
throw new IOException();
}
} // end of try
catch (IOException e) { // in case for some reason the output file could not be created
System.err.format("IOException: %s%n", e);
e.printStackTrace();
}
} // end main method
}
The most egregiously redundant code construct I often see involves using the code sequence
if (condition)
return true;
else
return false;
instead of simply writing
return (condition);
I've seen this beginner error in all sorts of languages: from Pascal and C to PHP and Java. What other such constructs would you flag in a code review?
if (foo == true)
{
do stuff
}
I keep telling the developer that does that that it should be
if ((foo == true) == true)
{
do stuff
}
but he hasn't gotten the hint yet.
if (condition == true)
{
...
}
instead of
if (condition)
{
...
}
Edit:
or even worse and turning around the conditional test:
if (condition == false)
{
...
}
which is easily read as
if (condition) then ...
Using comments instead of source control:
-Commenting out or renaming functions instead of deleting them and trusting that source control can get them back for you if needed.
-Adding comments like "RWF Change" instead of just making the change and letting source control assign the blame.
Somewhere I’ve spotted this thing, which I find to be the pinnacle of boolean redundancy:
return (test == 1)? ((test == 0) ? 0 : 1) : ((test == 0) ? 0 : 1);
:-)
Redundant code is not in itself an error. But if you're really trying to save every character
return (condition);
is redundant too. You can write:
return condition;
Declaring separately from assignment in languages other than C:
int foo;
foo = GetFoo();
Returning uselessly at the end:
// stuff
return;
}
I once had a guy who repeatedly did this:
bool a;
bool b;
...
if (a == true)
b = true;
else
b = false;
void myfunction() {
if(condition) {
// Do some stuff
if(othercond) {
// Do more stuff
}
}
}
instead of
void myfunction() {
if(!condition)
return;
// Do some stuff
if(!othercond)
return;
// Do more stuff
}
Using .tostring on a string
Putting an exit statement as first statement in a function to disable the execution of that function, instead of one of the following options:
Completely removing the function
Commenting the function body
Keeping the function but deleting all the code
Using the exit as first statement makes it very hard to spot, you can easily read over it.
Fear of null (this also can lead to serious problems):
if (name != null)
person.Name = name;
Redundant if's (not using else):
if (!IsPostback)
{
// do something
}
if (IsPostback)
{
// do something else
}
Redundant checks (Split never returns null):
string[] words = sentence.Split(' ');
if (words != null)
More on checks (the second check is redundant if you are going to loop)
if (myArray != null && myArray.Length > 0)
foreach (string s in myArray)
And my favorite for ASP.NET: Scattered DataBinds all over the code in order to make the page render.
Copy paste redundancy:
if (x > 0)
{
// a lot of code to calculate z
y = x + z;
}
else
{
// a lot of code to calculate z
y = x - z;
}
instead of
if (x > 0)
y = x + CalcZ(x);
else
y = x - CalcZ(x);
or even better (or more obfuscated)
y = x + (x > 0 ? 1 : -1) * CalcZ(x)
Allocating elements on the heap instead of the stack.
{
char buff = malloc(1024);
/* ... */
free(buff);
}
instead of
{
char buff[1024];
/* ... */
}
or
{
struct foo *x = (struct foo *)malloc(sizeof(struct foo));
x->a = ...;
bar(x);
free(x);
}
instead of
{
struct foo x;
x.a = ...;
bar(&x);
}
The most common redundant code construct I see is code that is never called from anywhere in the program.
The other is design patterns used where there is no point in using them. For example, writing "new BobFactory().createBob()" everywhere, instead of just writing "new Bob()".
Deleting unused and unnecessary code can massively improve the quality of the system and the team's ability to maintain it. The benefits are often startling to teams who have never considered deleting unnecessary code from their system. I once performed a code review by sitting with a team and deleting over half the code in their project without changing the functionality of their system. I thought they'd be offended but they frequently asked me back for design advice and feedback after that.
I often run into the following:
function foo() {
if ( something ) {
return;
} else {
do_something();
}
}
But it doesn't help telling them that the else is useless here. It has to be either
function foo() {
if ( something ) {
return;
}
do_something();
}
or - depending on the length of checks that are done before do_something():
function foo() {
if ( !something ) {
do_something();
}
}
From nightmarish code reviews.....
char s[100];
followed by
memset(s,0,100);
followed by
s[strlen(s)] = 0;
with lots of nasty
if (strcmp(s, "1") == 0)
littered about the code.
Using an array when you want set behavior. You need to check everything to make sure its not in the array before you insert it, which makes your code longer and slower.
Redundant .ToString() invocations:
const int foo = 5;
Console.WriteLine("Number of Items: " + foo.ToString());
Unnecessary string formatting:
const int foo = 5;
Console.WriteLine("Number of Items: {0}", foo);