if, for, while は1行でも中括弧(ブロックマーク)で囲う

どうも、スィンです。

Apple史上最悪のセキュリティバグか、iOSとOS XのSSL接続に危険すぎる脆弱性が発覚──原因はタイプミス?

2014年にこのようなニュースが有りましたが、これは

「コピペが悪い。またコピペしたでしょ!」とか
「こんなの書いてて気づかないのかよ!」とか
「邪悪なgotoをなぜ使ってるんだ!」とか
「単価の低いプログラマを使っているのか!」とか
「結局 fail に飛ぶのに失敗と判定されないのはなぜなんだ!」とか

まぁ、皆さんも色々と指摘したい箇所はあるかと思いますが、一番大きな問題は、

「テストしてないでしょ。テスト漏れでしょ、ちゃんとテストしろよ!」

ってことなんですよね。テストしてください。

では、テストをちゃんとすべきなのはわかって頂けた上で、このようなことを防げるよう日常的に対策をしておきましょう。

[code lang=”java” collapse=”false”] package net.sinrpoject.lesson;

public class IfElseSample {

public static final String TEXT_SPLITTER = " ——- ";

public static final String TEXT_OK = "OK";
public static final String TEXT_NG = "NG";

/**
* @param args
*/
public static void main(String[] args) {
String value = TEXT_OK;
String value2 = TEXT_NG;

System.out.println(TEXT_SPLITTER + "func1(\"OK\")" + TEXT_SPLITTER);
func1(value);

System.out.println(TEXT_SPLITTER + "func1(\"NG\")" + TEXT_SPLITTER);
func1(value2);

System.out.println(TEXT_SPLITTER + "func3(\"OK\")" + TEXT_SPLITTER);
func3(value);

System.out.println(TEXT_SPLITTER + "func3(\"NG\")" + TEXT_SPLITTER);
func3(value2);
}

public static void func0(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");

System.out.println("終わり");
}

public static void func1(String value) {
if (TEXT_OK.equals(value))
System.out.println("OKです。");
System.out.println("OKの2行目です。");
if (TEXT_NG.equals(value))
System.out.println("NGです。");
System.out.println("NGの2行目です。");

System.out.println("終わり");
}

public static void func2(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
}

System.out.println("終わり");
}

public static void func3(String value) {
if (TEXT_OK.equals(value)) {
System.out.println("OKです。");
System.out.println("OKの2行目です。");
}
else if (TEXT_NG.equals(value)) {
System.out.println("NGです。");
System.out.println("NGの2行目です。");
}

System.out.println("終わり");
}
}
[/code]

「func0() を作ったんだけど、OK と NG のケースにてそれぞれ2行以上処理したくなったので func1() にしました!」

というところで意図しないバグが生まれています。func1() では 引数が “OK” の場合に「NGの2行目」が意図せず出力されています。逆に引数が “NG” の場合も「OKの2行目」というのが出力されてしまっています。この手のコードで行を追加するときにこの問題が発生することがあります。行を追加するときは「中括弧がついていなければ付けないと・・・」という判断と対応が必要になります。

対策として

「if, for, while は、本体が1行でも中括弧(ブロックマーク)で囲う」

ことをコーディング規約にしてしまいましょう。func2(), func3() はそのように変更したものです。また、どちらも ture になる条件式ではないため「if-else」に変更しました。

インデントはただの見た目です。ただし人間はその見た目に騙されるのです!対策をしておいて損はないです。忘れ物が多い人は、前日に準備すると忘れ物が減りますよね。それと同じです。

バグ発生させた上司Aさん「でも、カッコがない方がカッコイイだろ!」
バグ対応した部下Bさん「何時間も原因を探した結果がカッコ不足が原因って、カッコつけたはずなのに超絶カッコ悪いっすよね!」
バグ発生させた上司Aさん「省略形があるのに使わいとかバカっぽいだろ!」

真実は小説より奇なり。

今回はここまで!ではでは!

Leave a comment

メールアドレスが公開されることはありません。

*

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)