- Method or function calls that do nothing of value.
Not necessarily bad. Methods in a base class often call empty methods that are meant as override points for subclasses. Example: Cocoa Touch's UIView has a -didAddSubview:
method that's documented as doing nothing in the default version. UIView's -addSubview:
method has to call -didAddSubview:
even though it does nothing because subclasses may implement it to do something. Methods that do nothing and the reasons for them should be documented, of course.
If an empty or useless function/method is obviously there for reasons historical, it should be excised. Take a look at earlier versions of the code in your source code repository if you're not sure.
- Redundant checks done in a separate class file, object or method.
Hard to say if that's okay without some context. If the checks are clearly done for the same reason, it may mean that there's not a clear separation of responsibilities and some refactoring is called for, especially when both checks result in the same action being taken. If the action resulting from the both checks is not the same, then the two checks probably are being done for different reasons even if the condition is the same, and that's likely okay.
- if statements that always evaluate to true.
There's a big difference between:
if (1) {
// ...
}
and:
if (foo() == true) {
// ...
}
where foo()
happens to always return true
.
The first case happens a lot when people are debugging. It's easy to use an if (0) {...
to temporarily remove a chunk of code while you're trying to isolate a bug, and then change the 0
to 1
to restore that code. The if
should be removed once you're done, of course, but it's easy to forget that step, or to miss one or two if you've done it in several places. (It's a good idea to identify such conditionals with a comment that you can later search for.) The only harm is the confusion it might cause in the future; if the compiler can determine the value of the condition at compile time, it'll remove it entirely.
The second case can be acceptable. If the condition represented by foo()
needs to be tested from several places in the code, factoring it out into a separate function or method is often the right thing to do even if foo()
always happens to be true right now. If it's conceivable that foo()
might eventually return false
, then isolating that condition in a method or function is one way to identify all the places where the code relies on that condition. However, doing that does create some risk that the foo() == false
condition will go untested and could lead to problems later; the solution is to make sure that you add unit tests that explicitly test the false
case.
- Threads that spin off and do nothing of note.
This sounds like an artifact of history, and something that could be identified either during a code review or through periodic profiling of the software. I suppose it could be created intentionally, but I have a hard time imagining that someone would actually do that on purpose.
if (false) {...}
blocks are great for commenting out code! </sarcasm>