2

When reviewing code, I prefer to read if statements that explicitly demonstrate that a fork in code execution may occur:

if ( isFoo(baz) ) {
    runBar();
}

When scanning hundreds of lines of the nonindented version, it is not obvious that a conditional may or may not occur:

boom += 1;
baz = getBaz(boom);
if (isFoo(baz)) runBar();
boing = boom + baz;

So when is it considered all right to single-line if statements? I'm willing to put up with it if the conditional is on a die(), return, or exception, because in those cases at least the current method ends.

if (isFoo(baz)) die("No more foo!");

Are there any other "good" uses for single-line if statements? How strictly should the practice be avoided? Note that I am explicitly asking about the lack of an indented line to indicate that a condition may or may not occur, I am not asking about the use of braces. Although I would appreciate all opinions in the comments, answers should address objective reasoning, such as maintainability or extensibility of code.

This is not a dupe of Single statement if block - braces or no because this question does not ask about braces. This is not a dupe of Single Line Statements & Good Practices because that question does not address the crux of this question: the ability to determine that some lines of code may or may not be run, thus leading to divergent code paths.

14
  • 3
    I see your point. However, the answers there might answer your question; this is something primarily opinion-based.
    – mike
    Jul 1, 2015 at 13:54
  • 2
    Definitely subjective. I use them to check for nulls, and very simple/clear statements, just because I feel like conserving space. And who doesnt like elegant one liners: if(obj == null) break;
    – CodyF
    Jul 1, 2015 at 14:41
  • 2
    "When to use single-line if statements?" Never. (please!)
    – utnapistim
    Jul 1, 2015 at 14:44
  • 3
    @CodyF, And who doesnt like elegant one liners: if(obj == null) break; I don't; every time I find one in the current code base, it's a reading interruption (as in "WTF?! oh! same line!"). I have checked out more than a few files, just to fix the damn same-line ifs and commit again.
    – utnapistim
    Jul 1, 2015 at 14:47
  • 3
    I'm not convinced either duplicate link is relevant when you read past their titles.
    – gbjbaanb
    Jul 1, 2015 at 15:53

3 Answers 3

15

The only time to use a single-line if statement is when you have a lot of them and you can format your code to make it very clear what is happening. Anything else is not clear and will lead to errors.

eg.

if (x) do_stuff();

is terrible. When mixed in with other code, it does not clearly show the conditional statement, and some people will confuse the following line as a badly-indented conditional. This applies to all statements, especially if they are die(), return or throw. It has nothing to do with the running of the code, its all about the readability.

if (a) do_a();
if (b) do_b();
if (c) do_c();

this is much better than putting the conditionals on the next line as its clearer what is intended, there is no scope for confusion.

2
  • 13
    I would contend that even for single line if, to avoid future errors one should consider if (a) { do_a(); } with the braces. Yes, they're unnecessary but it will avoid static analysis warnings and make it harder to make a mistake in the future.
    – user40980
    Jul 1, 2015 at 13:31
  • that would usually be the argument to use a statemachine switch
    – Peter
    Jul 11 at 6:20
10

I always prefer the version with braces.

  1. If I don't always use the braces, then I may forget to put them when there is more than one statement in the block.
  2. IDEs used by other team members can reformat the code automatically to move the statement to the new line, thus making it much more error prone in the future.
  3. Merging the code across the branches is more error prone if the if statement is a conflicting spot. The probability for error is even higher if the person doing the merge is not completely familiar with the merged changes.
  4. A statement not-belonging to the block may be included in it later by mistake (I add new statements to the block, so I need to add braces, but because of indentation or similar visual effects I also include a statement that should be left out of the block).
4

I would propose an alternative answer. I prefer single liners when the condition inside is really a single line and is relatively isolated from the rest of the conditions.

One great example is:

public void DoSomething(int something) {
     // Notice how easily we can state in one line that we should exit the method if our int is 0.
     if(something == 0) return;

     CallAnotherMethodHere(something);
}

A bad example(in my opinion) would be what @gbjbaanb mentioned:

if (a) do_a();
if (b) do_b();
if (c) do_c();

To me, this is a switch statement and should be written as such:

switch(something) {
    case "a":
        do_something_to_a();
        break;
    case "b":
        do_something_to_b();
        break;
    case "c":
        do_something_to_c();
        break;
    default:
        break;
}

Much more readable IMHO and more efficient as variable needs to be evaluated only once VS running through all the if statements although gains are negligible.

10
  • 1
    Thank you. The OP also mentions that return statements are an exception that should be allowed, as the method ends there.
    – dotancohen
    Jul 2, 2015 at 16:41
  • 4
    Your example assumes that a,b, and c are mutually exclusive.
    – Brian
    Jul 2, 2015 at 16:54
  • 2
    @Brian You are correct, because if they are not, I would start looking at the design because your method is responsible for a bunch of operations, and that's not a good sign.
    – Alexus
    Jul 2, 2015 at 17:21
  • 2
    Ugh... you prefer 13 verbose lines to 3? (Which, by the way, are far more readable due to the obvious repetition structure. And there's no chance of misplaced breaks.) Efficiency is a non-issue since optimizers are usually smart enough for something this simple. Nov 9, 2018 at 21:30
  • 1
    They're logically equivalent. This is simple enough that I'm sure an optimizing compiler would generate the same assembly for both. Maybe I'll test it out when I get home. Nov 15, 2018 at 2:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.