2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

if 文の中括弧の位置はなぜ K&R 派が増えたのか

Last updated at Posted at 2021-07-30

先に結論だけ書いておきますが、なぜ K&R 派が増えたのかはよくわかりませんでした。

もういい加減あんたのコードを読む気になれない

if (((g_flagA == false) && (g_conditionA != 1)) ||
	(g_flagB == true) ||
	(g_oldData1 != g_newData1) ||
	((g_flagC == true) && (g_conditionC == 0)) ||
	((g_flagD == true) && (g_conditionD == 0)) ||
	(g_oldData2 != g_newData2)) {
	HogehogeFugafuga_function();
	PafupafuMomimomi_function();
	HogehogeFugafuga_changeData();
	HogehogeFugafuga_copyData();
	g_flagF = true;
}

こんな感じの if 文が出てきました。g_ はグローバル変数に付ける規約なので仕方なし。
まずとりあえずこれがどういう条件文でどこからが命令文なのか、ぱっと見で分からないところが怖い。
こういうソースコードならせめて中括弧は改行くらいすまいか?

ところでどうして中括弧を右に付けたいのだ?

古い VC で C++(C言語) を始めた自分は当時の参考書を読みながらそれを真似して書いてました。多分その影響なのか中括弧はすべて改行します。
関数定義では改行するのに if 文で改行しない人はどういう基準でそうしてるのかよくわかりません。

if( a == b )
{
	hoge( a * b );
}

こんな感じに、広大にスペースを入れまくり、中括弧はほぼ左にします。その反面 case 文とかはなるべく1行で書きます。

switch( condition )
{
	case C_1: { Hoge_function_1(); }; break;
	case C_2: { Hoge_function_2(); }; break;
	case C_3: { Hoge_function_3(); }; break;
	case C_4: { Hoge_function_4(); }; break;
	default: break;
}

整然と並んでいる方がおかしいところに気づきやすいというメリットを優先します。機械的に改行すべきとか言う人はなんでそんなに行数を増やしたがるのでしょうか。

職場のコーディングスタイルが気がつくと K&R の方が多い

うちの職場はコーディングスタイルについては自由なんです。命名とかの規約はあります。
ぶっちゃけ自分のスタイルは MFC などの影響を受けているので割と新しくて流行っている方、と思っていたのですがどうやらそうでも無いらしい...
仕事のコードを見ても if 文の中括弧は右端に書く人が多いらしいです。

BSDスタイルを推す理由

可読性は確実に高い

まず最初の例文がわかり易い例でしょうか。いや、分かりにくいという例でもあります。if 文が複雑になるほどに、肝心の中身との分離が見にくくなりますね。
これを bool変数で置き換えるべきだ、という意見も出るのでしょうがそれはそれです。関係ありそうで関係ないと思います。

ブロックはどうする?

if でも for でもないただのブロックを書くときは左側に中括弧を書かざるをえません。ならば一貫性を保つために常時左が良いのです。

プリプロセッサでの切り替えもしやすい

#if X
	if( a )
#elif Y 
	if( b )
#else
#endif
	{
		f();
	}

ちょっとアレな例文ですがあくまで例ということで。
if 文自体を無かったことにも出来るわけです。

else の扱いが自動で統一される

実は K&R な人の一部は else と中括弧の関係がまちまちだったりします。

} else {
...
}
else {

左揃えならこれはまず統一されます。

ついでだけど、どうして if ( の間にスペース入れるの?

if と ( の間のスペースってどうして入れるんでしょう?
というのも関数名と括弧にスペース入れる人ってほとんどいませんよね?なのに if の後にスペース入れる意味がわからない。

if (a)		// 好きじゃない
if( a )		// これが好き
func( a );	// これと統一感

if を見て関数と間違える奴はいない、と断言しても良い気がします。間違えたならまず先に関数の方をどうにかしろ!
関数と間違えず、見やすさも別に損なわれないのに人気がないんですよね。

感覚的には if (a) と書いてしまうと if ○○ 的に見える、つまり「a を括弧でくくっている」ように見えるのです。
if( a ) と書けば「if() の中に a が有る」気分です。
規格上も () は省略できないので離す意味がないと思うんです。

怒られそうだけど実は有り

最後に嫌がられそうだけど慣れれば使えるスタイルをご提案。

if( data < 0 )
{
	hoge();
}
else switch( data )
{
	case 0:
	{
		fuga();
	}
	break;

	default: break;
}

else 文に switch を直結するやり方です。
まあ else if と本質的には同等なのですがほとんどやる人いないですよね。
でも評価対象が同じだと一貫性もあるので個人的に好きです。

最初の例文を自分流で書く
if(  ( !g_flagA && ( g_conditionA != 1 ) )
	|| g_flagB
	|| ( g_flagC && ( g_conditionC == 0 ) )
	|| ( g_flagD && ( g_conditionD == 0 ) )
	|| ( g_oldData1 != g_newData1 )
	|| ( g_oldData2 != g_newData2 )
)
{
	HogehogeFugafuga_function();
	PafupafuMomimomi_function();
	HogehogeFugafuga_changeData();
	HogehogeFugafuga_copyData();
	g_flagF = true;
}

こうなりました。なるほど、全体としては or で構成された条件文ですね。このように書くと分かりやすいです。
ここで一つ自己矛盾に思える箇所が if( は改行しないのか、というところですね。でもそこで改行を入れると 2行改行が入ります。

if
(
	   ( !g_flagA && ( g_conditionA != 1 ) )
	|| g_flagB
)
{
	// 中略
}

これは...むしろ見にくいと思いません?さじ加減というか塩梅というか、過ぎたるはうにゃららですよね。

2
3
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?