Mukai Systems

Single statement non-braced if

C系の言語では「if文に単文を使用してはならない」というコーディングスタイルが採用されることが多いように思う。

かくいう私は、積極的に使用してもよい派である。この記事の趣旨は、個人が趣味でコーディングをする場合は、積極的に使ってみてはどうかというものである。あたりまえの話だが、多人数で開発する場合はコーディングスタイルが規定されているべきであり、それに従うべきである。

少し調べてみると、興味深い投稿があった。

Which is better/more generally accepted?

This:
if(condition)
{
  statement;
}
Or:
if(condition)
  statement;

-- Stack Exchange: Single statement if block - braces or no?

単文を使用すべきでないとする代表的な理由は、「文を追加する際に複文にすることを忘れる」というものだろう。

I always use brackets just to be safe.

It's fine when you write it, but you know somebody will come along in the future and insert another statement without putting brackets around it.

かれこれ10年以上プログラムを書いているが、そのようなミスをしたことがない。インデントが自動で行われる環境であれば、視覚的に気づけると思う。

私と同じような意見があった。一方で、そういった事象に遭遇した人もいるらしい。多人数で開発する際は様々なスキルの人が参加しうるわけだから、単文のifは禁止しておくべきなのかもしれない。1

Have people really seen this happen?

I don't think I've ever seen this in 10 years of programming.

Maybe I've just been too sheltered.

...

I'd love to say no, but sadly I have seen it.

次に多い意見として「可読性が低い」というものがあった。「コードゴルフではない」と辛辣なコメントである。

if (x == 5) Console.WriteLine("It's a five!");

Brevity for sake of readability? Absolutely not.

It's code, not a golf contest.

私はこれが読みやすいと思っているので、この意見は衝撃的だった。結局のところ「可読性」が高いと思えるかどうかは「慣れ」によるところが大きいのだと思う。

私が積極的に単文を採用する理由は可読性が高くなると思うからである。プログラムの行数は可読性と密に関係があると思う。Paul Grahamは「素晴らしきハッカー」で以下のような考察をしている。

友人の幾人かは、ハッカーの集中力に関して言及した。一人の言葉を借りれば、「他の全てのことを頭から追い出せる」能力だ。私も確かにそれには気づいていた。また、何人かのハッカーが、ビールを半杯でも飲んだら全くプログラムできなくなると言っているのも聞いたことがある。ハッキングは、ある種の特殊な集中能力を必要とするのかもしれない。素晴らしいハッカーはたぶん、非常に大きなコンテキストを頭の中にロードすることが出来て、したがってコードを一行眺めている時にも、その行だけでなくそれを取り巻くプログラム全てを見ているのかもしれない。ジョン・マクフィーはビル・ブラッドレイのバスケットボール選手としての成功は、彼の並外れた周辺視に依っていたと書いていた。通常、完全な視力は、だいたい47度の垂直周辺視角を持っている。ビル・ブラッドレイは70度の視角を持っていた。彼は床を見つめていながら、バスケットを観ることが出来たのだ。素晴らしいハッカーは、そのような生まれつきの能力を持っているのかもしれない。(私は密度の高い言語を使うことでずるをしている。それは実質的にコートを狭める効果を持っているからだ)。

-- Practical Scheme: 素晴らしきハッカー

Googleのコーディングスタイル

参考までに、Googleがコーディングスタイルを公開していたので確認してみた。確認した範囲では、原則禁止とし例外的にいくつかの場合は認めているようであった。

C++

Google C++ Style Guideより。

Use curly braces for the controlled statements following if, else if and else.

...

For historical reasons, we allow one exception to the above rules:
if an if statement has no else or else if clauses, then the curly braces for the controlled statement or the line breaks inside the curly braces may be omitted if as a result the entire if statement appears on either a single line (in which case there is a space between the closing parenthesis and the controlled statement) or on two lines (in which case there is a line break after the closing parenthesis and there are no braces).
For example, the following forms are allowed under this exception.

    if (x == kFoo) return new Foo();
    
    if (x == kBar)
      return new Bar(arg1, arg2, arg3);
    
    if (x == kQuz) { return new Quz(1, 2, 3); }

Objective-C

Google Objective-C Style Guideより。

Braces may be omitted when a loop body or conditional statement fits on a single line.

// GOOD:
    if (hasSillyName) LaughOutLoud();
    
    for (int i = 0; i < 10; i++) {
      BlowTheHorn();
    }

// AVOID:
    if (hasSillyName)
      LaughOutLoud();               // AVOID.
    
    for (int i = 0; i < 10; i++)
      BlowTheHorn();                // AVOID.

If an if clause has an else clause, both clauses should use braces.

// GOOD:
    if (hasBaz) {
      foo();
    } else {  // The else goes on the same line as the closing brace.
      bar();
    }

// AVOID:
    if (hasBaz) foo();
    else bar();        // AVOID.
    
    if (hasBaz) {
      foo();
    } else bar();      // AVOID.

JavaScript

Google JavaScript Style Guideより。

Braces are required for all control structures (i.e. if, else, for, do, while, as well as any others), even if the body contains only a single statement. The first statement of a non-empty block must begin on its own line.

Disallowed:

    if (someVeryLongCondition())
      doSomething();
    
    for (let i = 0; i < foo.length; i++) bar(foo[i]);

Exception: A simple if statement that can fit entirely on a single line with no wrapping (and that doesn’t have an else) may be kept on a single line with no braces when it improves readability. This is the only case in which a control structure may omit braces and newlines.

    if (shortCondition()) foo();

[1] そのような環境では、コーディングスタイルで防げない問題が他にも山積みな気がする。