tags:

views:

577

answers:

19

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?

+2  A: 

Returning uselessly at the end:

   // stuff
   return;
}
WW
+2  A: 

Using .tostring on a string

WW
+8  A: 
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 ...
Otherside
I think you beat me to it by a few seconds!
Paul Tomblin
Yeah, I must have been slightly faster. I did upvote yours though because of the humor :)
Otherside
+7  A: 
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.

Paul Tomblin
Don't give 'em reverse advice, it'll just confuse them.
Johan
+3  A: 
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
}
Nick Johnson
That construct could be argued as valid if you're the "multiple returns voilates structured code" type.
Paul Tomblin
You need a better example. With only one level of nesting, the "early return" style is no better. In that sample I prefer the former. But I know what you're getting at and agree with the idea.
Steve Fallows
Even with only one level of nesting, 'early return' still saves you that level of nesting. I don't see why one level is no better but 2+ levels is. :)
Nick Johnson
Edited it to make a more egregious example anyway.
Nick Johnson
Well, at least for me one level of conditional reads very naturally with no confusion.
Steve Fallows
+1, early returns are so much more readable!
Adrian
+2  A: 

I once had a guy who repeatedly did this:

bool a;
bool b;
...
if (a == true)
    b = true;
else
    b = false;
Steve Fallows
b = a ? true : false;It depends, would you want b to equal 17 if that was what a equalled?
Mez
+2  A: 

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.

Otherside
For debugging though, deleting the function often isn't an option (if it's called in many places), commenting the body doesn't work if there's nested comments, and deleting the code means you have to save it somewhere. The 'real WTF'(tm) is leaving the exit statement in.
Nick Johnson
Deleting the code should always be an option because you have source control. so the Real WTF is not having source control.
mattlant
heh, i as i continue reading someone has mentioned that already :)
mattlant
I ran into this case with code fresh out of source control from a coworker. Made for some headscratching, even with 2 guys looking at that code :)
Otherside
+3  A: 

Declaring separately from assignment in languages other than C:
int foo;
foo = GetFoo();

RossFabricant
I actually do that quite often in C++ with non built-ins, where I may or may not want to add stuff to a vector for example.
Dominic Rodger
+8  A: 

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.

RossFabricant
+5  A: 

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);

:-)

zoul
A compilers dream :)
leppie
+1  A: 

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();
    }
}
ComSubVie
I'll disagree on that one.The original code doesn't perform any worse, and the actual work is in the code at the same level of nesting -- Which I find more readable.It really comes down to a team style convention.
chris
I find the first case easier to read too. Maybe the visual symmetry helps.
Thomas Bratt
It depends. If we're talking about an early exit, then the second form is better; if the two cases are of similar importance, then I would go for the first form.
Diomidis Spinellis
A: 

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.

RossFabricant
+3  A: 

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;
PiedPiper
+2  A: 

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.

Panos
+2  A: 

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)
Panos
+2  A: 

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);
}
Diomidis Spinellis
This is only valid in those cases, when you know exactly how big the buffer must be. I also had problems on some linux distributions - they would simply refuse to give me a buffer of 4k bytes.
Paulius Maruška
Of course! I'm talking about cases where the malloc is for a fixed-size chunk of memory.
Diomidis Spinellis
+1  A: 

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.

EvilTeach
A: 

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);
ilitirit
+2  A: 

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.

Nat
+1 for redundant factories
jk
Agreed about redundant factories. Obviously, the problem with them is that it takes too much typing to write them. So I made a generic version: http://gist.github.com/629145
Sam Pearson