キャリア20年超。ずっとプログラマで生き延びている女のコラム。

カッコをつけたコードはカッコわるいのか論争

»

 プログラマならC/C++を知らなくても、

if (buffer == null) {return;}



if (buffer == null) return;


は同じ動作をするということはお分かりかと思います。

 正式な言い方があるのか分かりませんが、「省略が許可されている記述」というやつです。

 わたしは「省略が許可されてても省略しない派」(←どういう派閥?)なので、常にカッコでくるむのですが、わたしのコードを読んだ人が「これってこういう書き方していいんだよ」とご丁寧にもカッコをはずしてしまったことがありました。

 「それくらい知ってるんですけど」

 「なら、なんでわざわざカッコつけてんの?」

 「どっちでもいいんならカッコをつけた方が安全じゃないですか」

 「どういうこと?」

 当時、わたしは結合テストで出てきたバグの原因調査をよくやらされていた(他の連中はテストで出たバグをつぶすのに忙しかったから)んですが、その時にこんな感じのバグをみつけたわけです。

if (buffer == null) pos++; return;


 前後の文脈からみるにこれは

if (buffer == null) return;


というコードに pos++; という処理を追加したときに、カッコも付け加えることを忘れた結果です。正解は当然、

if (buffer == null) {pos++; return;}


です。

 間抜けだとは思いますが、人間てのはこんな簡単なミスをよくやります。なにげない修正だからこそうっかりするんだと思います。

 そのコードを見た時にわたしは思ったわけです。どんな時でも最初っからカッコをつけておけばこんなバグ発生しないじゃん!

 というわけで、わたしはそれ以来、省略形を使わないようになりました。

 そんな説明をして、「省略形はバグを生む温床になるから使わない」と言ったんですが、相手は納得しませんでした。

 「でも、省略形があるのに使わないってバカっぽくない?」

 「何時間も原因を探した結果がカッコが足りないだけって方がバカっぽいですよ」

 「でも、カッコがない方がカッコイイだろ」

 「なんでカッコがない方がカッコイイんですか?」

 「見た感じすっきりしててカッコイイ」

 「でも、カッコつけてカッコつけないでバグだす方がカッコワルイですよね!」

(←日本語がわかりにくくてすみません)

 といった感じでしばらく押し問答を続けたんですが、相手があくまでもカッコをつけないことにこだわるので、ついにキレて「わたしよりもバグの発生率が低くなったら、言うことききます!」と言い切ったら、無言で立ち去っていきました。

 カッコがない方が見た目がすっきりしている、というのはわかります。けれど、仕事で書いているコードは安全第一です。どんな小さな芽でもつぶしておくべきだと思います。だって、バグのあるコードはカッコワルイもの!

 プログラマってのはコーディングスタイル(改行位置とか命名方法とか)に関していろいろなこだわりを持っているもので、チーム内のコードなら署名を見なくても誰がそれを書いたのかすぐに分かります。

 人それぞれの美意識や読みやすさがあるんでしょうから、それを尊重してあげたい気持ちはあるんですが、他人にそれを押し付けるのはいただけません。

 そもそも、あの人がなんであんなにカッコをつけないことにこだわったのかが、いまだに謎です。女には計り知れない男の美学とかいうものがあるんでしょうか……(それとも男のメンツってやつを傷つけちゃったのか?)。

Comment(81)

コメント

インドリ

>「省略が許可されている記述」というやつです。

それは多分センタックスシュガー(糖衣構文)です。


>。女には計り知れない男の美学とかいうものがあるんでしょうか……(それとも男のメンツってやつを傷つけちゃったのか?)。

うーんどうなんだろう・・・
私は男ですがこんな事考えた事ないです。
多分性別に関係なく、拘りが強い人が居るのでしょう。
プログラミングはやはり格好云々ではなく、作業効率とかチームワークを考えるべきですよね。

wona

はじめまして。
僕も省略しない派です。さらに処理が1行しかなくても
改行してインデントを入れます。

if (buffer == null) {
return;
}

見た目が揃っているほうが美しいと思うし、バグ発生率も下がると
思っているのでそうしています。
ただ、自分が読めるのであれば、他人のスタイルはとやかく言いません。

ちなみにコードだけじゃなく、メールもそれぞれ書き方にスタイルが
あって、名前見なくても誰が書いたかわかったりしません?

はがねのつるぎ

こんにちは。
わたしもカッコはつける派です。

JavaだとSunが推奨するコーティング規約で、
危ないので使うなとはっきり言い切ってます。

if statements always use braces {}.

http://java.sun.com/docs/codeconv/html/CodeConventions.doc6.html#431

仕事のコーディング規約に「Sunのルールに準ずる」とか入れておくと完璧です。

それでも言うことを聞かないヤツとは言い合っても不毛なので、
技術的にも、コミュニケーション的にも「要注意人物」扱いですね。

> 仕事のコーディング規約に「Sunのルールに準ずる」とか入れておくと完璧です。

弊社もこれを基準にしている。

たなか

最初に。
こういうのは、古来から続く「宗教論争」です。宗教論争なので、結論が出るはずも
ありません。また、宗教ですから、他人に布教するのは自分の信ずる神への忠誠の証
であり、行動としてはごく当然のものと言えます。男女を問う話ではなく、どれだけ
神への忠誠心があるかどうかに依存します。

さて、まずコメントすべきなのは、{}をつけないのが「省略記法」であるという認識
の誤りです。もともとifやforは言語仕様上、その後に「一つの文のみを指定できる」
ということになっています。一つの文しか指定できないところに、複数の文を書きたい
場合に、{}で括る「複文」を使用できる、ということです。
ですので、「省略できるのを省略しない」のではなく、「(バグ対策のために)常に
(わざわざ)冗長な表記で統一する」ということになります。この点、結果は同じなの
ですが立ち位置が変わると、行動に対する評価がずいぶん変わるように思います。

なお、バグを避けるのであれば、{}の有無よりは「一行に複数の文を書かない」という
方がよっぽど有効に機能するでしょうし、きちんと改行インデントしていれば、{}なし
でも例示のような誤りは起こり得ないでしょう。
{}なら軽いですが、たとえばPASCALのような言語で、begin-endでブロックを括る
というような場合でも常に括るべきか、というとやはり否定的になるのではないで
しょうか。
括弧を取ることにより、見た目がすっきりする、というよりは、行数の限られた
エディタでより多くの範囲を見通すことができるようになり、メンテがしやすくなる
という側面もあるでしょう。

最後に。私の宗派は、
・明確で単純な一文の場合は、{}で括らない
・上記でも、一行コメントを含む場合は、{}で括る
・forの中のifのように、複数のインデントが一気に解消される場合は、外側を{}で
括る
・{はif/elseと同じ行に置き、elseは}とは別の行に置く
というものですかねえ。c#では、行頭に{を置くなど、マイクロソフトのガイドラインに
従いますけれど(エディタの指示するがままに)。このあたりで、すでにsunのガイドライン
とも相違がありますので、sunのガイドラインにしても、絶対唯一の神とは言えません
(javaなら良いかも。c/c++にまでは流用というのは越権でしょう)。

開発責任者

普通に考えて、wonaさんの方法「{}をつける、改行する、インデントする」が安全ですね。弊社もこれで統一しています。
こういう、明らかに品質に直結する部分は必ず品質重視です。商用プログラミングでは基本だと思いますよ。私は男性ですが、カッコをつけないほうがカッコいいというのは理解できませんね・・・。単に意固地になったとか、ひっこみがつかなくなっただけでしょう。
少なくともカッコなしを押し通そうとした場合は、その人が品質を重視していないと考えざるをえないので、責任のあるポジションにはつけられないですね・・・。

しめさば

C/C++ ならば
 return;
じゃなくて
 return 0;
じゃないのか?とか
 return (0);
が正しいとか……(以下無限ループ)。

あ~り~

はじめまして。

>「わたしよりもバグの発生率が低くなったら、言うことききます!」
カッコいい!
私は、省略しない&インデントする派です。
理由は、コラム同様にバグ発生率が微妙にでも下がるから。

しかし、
「見た感じすっきりしててカッコイイ」は分かりますが、品質を
担保できることが前提と思いますが、世の中面白い方もいるものですね。

ちゃりお

カッコイイかどうかっていう理由だけなら主観的なものだし、「自分はカッコイイとは思わない」で済まないのかな。
自分も必ずカッコつけて次行にインデントします。バグの原因となりやすいかもそうですが、あとでデバッグ用に一時的に処理を追加したい場合にいちいちカッコをつける必要がないという理由も大きいかな。

hajime

自分は、読めれば別にどれでもいいです。
あちこちの現場でルールが違うので、それに合わせます。

1. 1関数あたりの行数が決まっている現場の場合(50行以上だと分割など)
  if (buffer == null) return;

2. K&R(?)を見てコーディング規約を作った現場の場合
  if (buffer == null){
    return;
  }

3. {}の位置を合わせたほうがよいという現場の場合
  if (buffer == null)
  {
    return;
  }

個人的に組む場合や、ルールがない場所で組むときは、
たなか さんのルールで書くことが多いです。
理由は画面内に1関数全体が見えたほうが処理内容が理解しやすいからです。

ただ {} ではなく () のほうには異常なまでにカッコつけます。
()関連のバグのほうが自分は面倒くさいですから。(マクロとか特に)

#それにしても毎回思うのですが、
#なぜ女性エンジニアの書く文章はいつも面白いのでしょうか。

Atsushi777

「仕事で書いているコードは安全第一です」などというなら、
if (buffer == null) はいただけないのでは?
間違って、if (buffer = null)と書いてしまいかねませんからね。

演算子の優先順位なんかも間違ったら困るので必ずすべてカッコでくくりましょう。

でも、そういうのって程度問題だし、
たとえば{}をつければ「必ず」安全側に傾くと言いきれないと思うんですけどね。

「省略が許可されている記述」だと思い込んでいる(正確な知識がない)あたりは、
「常に{}を書く」というマイルールを設定していることによる弊害である気がします。

ひでみ

こんばんはです。ひでみです。
カッコがどうのこうのという細かい話題にこんなにコメントをいただけるとは思ってもみませんでした。
いろいろと勉強になりました。ありがとうございました。

いつものことながら、コメント返しがしっかり書けなくてすみません。


インドリさん。いつもコメントありがとうございます。

> それは多分センタックスシュガー(糖衣構文)です。

ちゃんとした呼称があったんですね。教えてくださってありがとうございます。
さっそく「センタックスシュガー」でググってみたところ、このページのインドリさんのコメントがトップにでてきました。
ビックリした~。
「シンタックスシュガー」の方で大量に出てきました。
そういえば昔「センタックスエラー」と言っていた記憶があるんですけど、今は「シンタックスエラー」が主流ですよね。いつの間に……。

> 多分性別に関係なく、拘りが強い人が居るのでしょう。

それが男性の間でメジャーな意見なのかどうかを、私は割と気にするんですよ。
話し合いもしてないのに意見がまとまっちゃってて、それぞれに尋ねてみると「えっ? そういうもんなんじゃないの?」と男性陣がそろって答えるという事態によく遭遇するもので(それでおもわぬところで不利な立場に)。


wanoさん。

> 僕も省略しない派です。さらに処理が1行しかなくても
> 改行してインデントを入れます。
> if (buffer == null) {
> return;
> }

私も普段はそのように書きます。
今回はコラムとして読みやすいように一行にまとめてみたんですけど。

> ちなみにコードだけじゃなく、メールもそれぞれ書き方にスタイルが
> あって、名前見なくても誰が書いたかわかったりしません?

わかります!
件名のつけ方だけでわかる人もいたりします(笑)。


はがねのつるぎさん。

> JavaだとSunが推奨するコーティング規約で、危ないので使うなとはっきり言い切ってます。

それは知りませんでした。
なんか知らないことばっかしですね、私。


生島勘富さん。

>>> 仕事のコーディング規約に「Sunのルールに準ずる」とか入れておくと完璧です。
> 弊社もこれを基準にしている。

当時の職場にそのようなコーディング規約はありませんでした。
というか、Sunのルールというのも私は読んだことがありません(汗)。


たなかさん。
丁寧なご説明をありがとうございます。
軽い気持ちで書いたコラムをこんなに真剣に検討していただいて恐縮です。

> 男女を問う話ではなく、どれだけ神への忠誠心があるかどうかに依存します。

ものすごく納得しました。


開発責任者さん。

> 私は男性ですが、カッコをつけないほうがカッコいいというのは理解できませんね・・・。
> 単に意固地になったとか、ひっこみがつかなくなっただけでしょう。

私が受け流せばすむ話だったんですかねえ……。
「こんなことも知らないと思われてる!」と思って、ちょっと強く出すぎたのかもしれません。


しめさばさん。

> C/C++ ならば
>  return;
> じゃなくて
>  return 0;
> じゃないのか?

戻り値が void の場合は return; だと思いますが。


あ~り~さん。

>>> 「わたしよりもバグの発生率が低くなったら、言うことききます!」
> カッコいい!

実は言ったあとで、ちょっとおとなげなかった、とヘコんだんですが(苦笑)。


ちゃりおさん。

> 「自分はカッコイイとは思わない」で済まないのかな。

今になってみると私もそう思いますが、その時はその手を思いつきませんでした。


hajimeさん。

> #それにしても毎回思うのですが、
> #なぜ女性エンジニアの書く文章はいつも面白いのでしょうか。

面白いと思っていただけてうれしいです。
でも、女性エンジニアの文章が特におもしろいと感じたことはないですねえ。
女性同士ではわからないおもしろさ、というものがあるんでしょうか。


Atsushi777さん。

> たとえば{}をつければ「必ず」安全側に傾くと言いきれないと思うんですけどね。

カッコがあることでバグが発生するパターンの方が少ない、とは言い切れると思います。

鉄砲水

こんばんわ。

#define MACRO pos++;hoge++

if (buffer == null) MACRO ;

こんな感じの恐ろしいコードに出くわした事があります。
「自分でもやりかねない!!」と思ったので、
それ以来カッコは付ける事にしています。

最近(というほど最近でも無いのかな?)は、プログラミングの高信頼化
に関する研究も進んでいて、堅牢性を高めるソースコードの書き方は
「宗教」から「科学」に移り変わってきているようです。

「静的解析」でググると、以下がヒットしたりします。
http://www.atmarkit.co.jp/fjava/rensai3/eclipsetst02/eclipsetst02_1.html

また、
if (buffer = null)
とか、代入文なのに
buffer == null;
と書いたりとかは、C/C++ならコンパイラのワーニングレベルを上げれば
見つけてくれるかも知れません。(gcc4.xだったら見つけてくれたかな?)

見つけてくれるコンパイラなら、ワーニング除去の習慣を付ける事での
回避もアリかなと思います。

初めてコメントさせていただきます。

自分も他の方と同じように「カッコ付ける&改行する」派です。1行であっても常にカッコを付けますし、改行します。
「カッコイイ」「カッコワルイ」は主観でしかないので、自分は愚直でもバグを出さない方に倒したいです。
あ、でも「null == buffer」は絶対に書かないかも。
# 自分のモットーは「一番最適化が効かないのは人間」です。

> さっそく「センタックスシュガー」でググってみたところ、このページのインドリさんのコメントがトップにでてきました。
トップに出てくるのは「センタックスシュガー」が一般的には使われない言葉だからだと思います。
スペルは「Syntax sugar」ですが、ネイティブな発音ですと「Sytax」は「センタックス」と読むかもしれません。でも「糖衣構文」としての日本語であれば「シンタックスシュガー」と言う方がほぼ99%でしょう。
そもそもが、これは「糖衣構文」ですらありません。単なる『カッコをつけるかどうかの宗教論争』ですね。
間違った言葉を鵜呑みにしてしまうといろいろと損をしますので、自分で裏付けを取ってみることが大事だと思います。
私の発言も真実とは限りませんし。

teto

いつも楽しく読ませていただいてます。

私も今は省略しない派ですが、Javaを勉強し始めた頃は
「一行なら省略する。」と覚えてました。
本だとだいたい省略形の書き方を説明してあったり、試験でそういう知識を問われたりした記憶があります。。

「カッコがない方がカッコイイだろ」
といわれたら、私なら
「センスが出ますよね」
で流しちゃいます。コーディングルールなら従いますが、それ以外は個人のセンスかと。

インドリ

うわぁ細か!だから「多分」と書いてあるのにね。
コンパイラ的に言えば、if(式)statement だから元々そう解釈するんだけどね・・・

Atsushi777

> カッコがあることでバグが発生するパターンの方が少ない、とは言い切れると思います。

言い方は悪いですが、
そういう脳みそ使わなくてもルールを守ればバグが減らせるという姿勢が、
いざというときに重大な問題を引き起こしたりするのだと私は考えています。

#define MACRO pos++;hoge++
if (buffer == null) MACRO ;

みたいなのは、まさにマクロ側に問題があるのであって、
これをカッコの問題に矮小化してしまっていいものなのでしょうか?

カッコをつけていれば確かにこの問題はバグとして顕在化しないかもしれませんが、
その分潜在的な問題が解決されずに残るわけです。

そういうことに比べれば、カッコをつけるかつけないかは問題ではないと思います。

> 当時の職場にそのようなコーディング規約はありませんでした。
> というか、Sunのルールというのも私は読んだことがありません(汗)。

とりあえず、Sunのコーディング規約で縛ることにしています。
なぜかというと、(私は反対派ですけれど)オフショアするときに一番説得しやすいから(元々英語だし)

オフショアなどで母国語が違う人たちとまで、宗教戦争するのはとてつもなく無意味なので、そのプロジェクトにSunのコーディング規約を知らない人がいても、「世界標準だからで」押し切ります。

カッコいい/わるいっちゅーより、コードの「涼しさ」で判断してるよに思います僕の場合。
引数が想定される範囲内にないときに門前払いを食わせる、なんてときに

/* n > 0 なるべし! */
void f(int n) {
 if ( n <= 0 ) return;
 ...

こいつを

 if ( n <= 0 ) {
  return;
 }

って書くと暑苦しく感じるんですよね。
あ、でも

 if ( n <= 0 ) { return; }

ならそんなに悪くない。

noone

私の場合,演算子に優先順位があるケースでも明示的に括弧でくくるようにしています。

int a = b * c + d; // (*)

ではなく,

int a = (b * c) + d;

とか。

括弧を付け忘れて

int a = b * (c + d);

とするつもりが,(*)のように書いてしまったのではなく,自分が意図してこの順番で計算したいと考えたからこうしたんだということを,コードを読む他の人(1年後の自分含む)に伝えるためです。

まあ上の例は極端ですが,式に型キャストを含む時等は特に,キャストしてから計算するのか,計算してからキャストするのかをきっちり書いておきたいケースがままあります。

noone

私の場合,演算子に優先順位があるケースでも明示的に括弧でくくるようにしています。

int a = b * c + d; // (*)

ではなく,

int a = (b * c) + d;

とか。

括弧を付け忘れて

int a = b * (c + d);

とするつもりが,(*)のように書いてしまったのではなく,自分が意図してこの順番で計算したいと考えたからこうしたんだということを,コードを読む他の人(1年後の自分含む)に伝えるためです。

まあ上の例は極端ですが,式に型キャストを含む時等は特に,キャストしてから計算するのか,計算してからキャストするのかをきっちり書いておきたいケースがままあります。

else if についてコメントしてる人が誰もいませんね…

必ず {} つける派の人でも、以下のような書き方はよくやると思いますが、

if( hoge )
{
 // ...
}
else if( hage )
{
 // ...
}

これは書き方を変えれば、こういうこと

if( hoge )
{
 // ...
}
else
 if( hage )
 {
  // ...
 }

ですね。
2つ目の {} はあくまで if につくものであって、else にはついてないので、本当に「必ず {} つける」を徹底するなら、

if( hoge )
{
 // ...
}
else
{
 if( hage )
 {
  // ...
 }
}

ですね。

いや、俺も「必ず {} つける、ただし else if は例外」派ですけど。

ゆあん

そもそも1行に複数命令を書かない方がいいと思います。(例外はあります)
私は
if (buffer == null) return; も
if (buffer == null) {return;}も
書かなくて、必ず
if (buffer == null)
return;
と書きます。

まりも

カッコがないほうが美しいです。

なぜなら、行をまとめるための文法であるカッコが、
一行なのにくっついているのは明らかに冗長だからです。

そして、一般論として、
美しいコードは保守性が高いです。

ここまでは正論だと思う。

カッコをつけないのは、
そういう理由なのではないかな。


ただまあ、一般論というのには例外があるもので。
そして、この場合は昔から確認されている有名な例外。
だからまあ、付けといたほうがいい可能性が高いと思います。

インドリさん
> うわぁ細か!だから「多分」と書いてあるのにね。
これ、もしかして僕に対する返答だったりします?
思い違いならそれでかまいませんが、主語がないと単なる独り言と見なされちゃいますよ。
でもって、もし僕に対する返答だったとして「細かく考えるのは技術者としての性(さが)ですよ」と書いておきますね。

> コンパイラ的に言えば、if(式)statement だから元々そう解釈するんだけどね・・・
これもよくわかんない。どなたも(それまでの発言に限っていえば、インドリさん自身も)コンパイラの話はしていないですよね。
コンパイラと宗教論争がどう結びつくのかは、やっぱりわからないです。


Sunのコーディング規約で縛る、というはがねのつるぎさんや生島勘富さんの考えはよくわかります。
今回の論争のような「ぶれ」を信頼のおける第三者の規約でなくすという感じでしょうか。
自分の場合Javaの経験が少ないこともあって、Sunのコーディング規約を見たことはありませんが、職場でコーディング規約を設けるとしたら参考にするかもしれませんね。


まりもさんのおっしゃる「美しさ」は、結構人によって基準にばらつきがあると思うのです。επιστημηさんの「涼しさ」もそうですが。
επιστημηさんの場合は私もつきあいがそこそこあるので、言わんとする意図はなんとなくですが、伝わってくる気がします。あと、具体的なコードがあるので「こう言おうとしているのね」とわかるのかもしれません。まりもさんの「美しいコードは保守性が高い」も、言わんとすることはなんとなく伝わっていると思うのですが、文頭に書いたように美しさの基準が私とまりもさんとでは違うようなので、一概には言えないですね、と書いておきます。


とりあえず、ひでみさんは次にこういった論争にぶつかったら「カッコイイ」「美しい」以外の、論理的な解釈を要求してみてはいかがでしょうか。
相手の方にも美意識以外に何かそう言わんとする根拠があったのかもしれませんし。なかったかもしれませんけども。

ひでみ

こんばんわです。ひでみです。
たくさんのコメントありがとうございます。
カッコがつくのつかないのという細かい話におつきあいくださる方がこんなにいらっしゃるとは。
その細かい話にこだわってこういうコラムを書いた人に、そんなこと言われたかないでしょうけど(笑)。


鉄砲水さん。

> #define MACRO pos++;hoge++
>
> if (buffer == null) MACRO ;
>
> こんな感じの恐ろしいコードに出くわした事があります。

これは離れて書いてあったら(←普通は離れてる)気づかない可能性大ですね。
C++から離れて久しいんですが(あんなに愛してたのに!)、開発環境はどんどん進化していってるようですね。
どんどん取り残されてゆく……。


ぽぴ王子さん。

> # 自分のモットーは「一番最適化が効かないのは人間」です。
>
> 間違った言葉を鵜呑みにしてしまうといろいろと損をしますので、
> 自分で裏付けを取ってみることが大事だと思います。
> 私の発言も真実とは限りませんし。

私のモットーは、「人生の失敗原因のほとんどは、信じるべきものを信じなかったか、信じてはいけないものを信じてしまった、のどちらかだ」です。


tetoさん。

> 「カッコがない方がカッコイイだろ」
> といわれたら、私なら
> 「センスが出ますよね」
> で流しちゃいます。

それが大人の対応というものかと思います。
どうしてそれができないんだ、自分。


インドリさん。

> うわぁ細か!だから「多分」と書いてあるのにね。

プログラミング言語も日本語もあいまい表現(?)の取り扱い方は人それぞれのようです。


Atsushi777さん。

> 言い方は悪いですが、
> そういう脳みそ使わなくてもルールを守ればバグが減らせるという姿勢が、
> いざというときに重大な問題を引き起こしたりするのだと私は考えています。

こういう戒めをつくることにより、人間は必ず間違えるのだ、ということを常に自分に言い聞かせることができる、という解釈もできます。
これもまた「宗教論争」かもしれません。


生島勘富さん。

> Sunのコーディング規約を知らない人がいても、「世界標準だからで」押し切ります。

わかりやすいうえに世界共通で使えるというのがステキですね。


επιστημηさん。

> コードの「涼しさ」で判断してるよに思います僕の場合。

「カッコイイ」「カッコワルイ」論争に、「涼しさ」と「暑苦しさ」を投入しますか。
う~む。


nooneさん。
コメントが二重に入っちゃってるようですけど、片方を削除してしまってもよろしいですか?

> 私の場合,演算子に優先順位があるケースでも明示的に括弧でくくるようにしています。
> int a = b * c + d; // (*)
> ではなく,
> int a = (b * c) + d;
> とか。

それは私もやりますね。それで「うるさい」と言われたことがあります(苦笑)。


aetosさん。

> else if についてコメントしてる人が誰もいませんね…

else if を else と if に分離させたうえで両方にカッコをつけるという発想は、私にはありませんでした。
これはこれでおもしろい感じがしますが(うねっててかわいい)、ネストを増やすな、と怒られそうです。


ゆあんさん。

> そもそも1行に複数命令を書かない方がいいと思います。(例外はあります)

コラムに書くという例外でなければ、私も改行します。


まりもさん。

> カッコがないほうが美しいです。
> なぜなら、行をまとめるための文法であるカッコが、
> 一行なのにくっついているのは明らかに冗長だからです。

「ひとつのものをわざわざまとめている」という意識は私の中にありませんでした。
なるほど、そういう考え方でいけば「省略じゃない」ということになりますね(今頃、納得した)。
あちらが「省略」してるわけじゃなくって、私が「添加」しているということですか。

Azalea

宗教論争と言えば其の通り。
実益の観点で言えば、他人が読むならカッコを付ける。
自分一人ならカッコは付けない。何故なら面倒だから。

カッコを付けない場合は、必ず空行を入れる。
そうすれば見辛くもならないかと。

まったく関係ないですが、コンパイラの視点で言えば、
カッコは省略可能なのでは無く、複数の処理を一つのブロックとするために
付けただけ。
なので、省略が可能と言う表現は微妙かと。

僕は括弧付ける派ですねぇ
例え1行でも、後で処理を追加する際に括弧忘れのバグがおきることを警戒しています

自分だけで直ぐに作っておしまいだったら見た目もすっきりしたほうが良いのかもしれませんが、
お仕事で書くソースは後で見ず知らずの人が処理を追加する可能性があるので、
その時にバグの温床となる部分を作るのはよろしくないと考えています
となると、
括弧無しだと自分以外の誰かが自分の手を離れた上体で処理を追加した時に、
括弧を追加して処理を入れてくれるとは期待できません

ですので、括弧は入れておきます

四則演算の優先度やブールのANDやOR等も意味のある一纏りはきちんと括弧でくくるようにしています

また、if文ですが、
if(条件)
{
処理
}
で書きますねぇ

これは、他の人の書いた処理のバグつぶしの際に、
括弧の相方の位置を探す時に苦労したからです

{と}が同じインデントにあれば、
上下にたどれば見つけられます
無かったら、足りないって事ですね
これが、
if(条件){
処理
}
の場合、入れ子になっていると、
閉じが多かったり少なかったりしても、分かりにくいことがあります
というか、分かりにくくてなかなか気づけませんでした

というわけで、僕はくどいとか暑苦しいとか、すっきりしたほうが格好が良いとか
どーでも良くて、
後で(忘れたころの)自分や他人がみて難解なパズルを解かなければいけないのか、
単純な間違い探しで済むようになるのか、
そっちのほうが重要だと考えています。

まぁ、困るのは自分じゃないから格好がいいほうがいいといわれれば、それまでですが・・・

しかし、括弧とか格好とか、ひらがなで連呼すると、わけが分からなくなりますねw

undo

まともなエディタを使えばいいだけ。>入れ子、インデント

個別の構文スタイルよりも、同じプロジェクト内で、誰が書いたプログラムか分かるくらいスタイルがバラバラであるほうが問題でしょ。
私の理想は、「ソースプログラムに個性は要らない!」
誰が書いても同じ、誰でも読めるソースコードですね。そうなれば、一定の品質を保てるし、レビューが捗ります。

else ifの間に改行入れて分けているのを見たら、「バカか!」と思うだろうなぁ(^^;;
do {} while();のwhileの前も同様。

ひでみ

こんばんわです。ひでみです。
いつものことながら、コメント返しがひとまとめですみませんです。

Azaleaさん。

> 実益の観点で言えば、他人が読むならカッコを付ける。
> 自分一人ならカッコは付けない。何故なら面倒だから。

私は一人でもカッコをつけますね。
というか、完全に習慣化しちゃってて、無意識にカッコを打ってしまいます。


煉さん。

> 後で(忘れたころの)自分や他人がみて難解なパズルを解かなければいけないのか、
> 単純な間違い探しで済むようになるのか、そっちのほうが重要だと考えています。

数ヶ月前の自分は他人だった、ということはよくあります(苦笑)。

> しかし、括弧とか格好とか、ひらがなで連呼すると、わけが分からなくなりますねw

今頃、「括弧」って漢字で書けばわかりやすかったんだ、ということに気がつきました(←遅すぎる)。


undoさん。

> まともなエディタを使えばいいだけ。>入れ子、インデント

私はC/C++を開発していた時、ずっとviを使っていました。
viにそんな便利な機能はありませんけど、ものすごく使いやすくて「まともなエディタ」だと思っていましたよ(嫌う人が多かったけど)。

> 個別の構文スタイルよりも、同じプロジェクト内で、誰が書いたプログラムか
> 分かるくらいスタイルがバラバラであるほうが問題でしょ。

コーディング規約があれば当然それに従いますからそれなりに統一はされますけど、関数や変数の名前の付け方とか、関数の分割の仕方とか、if文の条件が複雑になった時にどのように記述するかとか、様々なところでどうやったってクセがでるのでやっぱりわかります。

> 私の理想は、「ソースプログラムに個性は要らない!」

チームの連中のコードを読んでいると、時々「ああ、あの人らしいなあ」と思ってニマッとしてしまいます。私の中でコードは「読み物」でもあるので、そういうことになるんだと思います。
仕事で書くコードは「製品」ですから、個性はいらない、と言われると社会人としては同意すべきなのかもしれませんが、なんとゆーか……つまらない……。

まりも

>まりもさんのおっしゃる「美しさ」は、結構人によって基準にばらつきがあると思うのです。

ちなみに、私個人の美的感覚で言うと、
「カッコなし」は美しく「ない」とおもいます。

理由はたぶん見慣れてないから。
カッコつけないで書くことほとんどないですしね。

ただまあ、Cの文法の規則からすると、
カッコなしのほうがシンプルで素直であると思うので、
両方に同じくらい見慣れた状況を想像すると、
たぶん美しく感じるのかなあと。

まあこのへんも含めて個人差だ言われればそれまでですが。

それに一般論だとしても、
現に例外を目の前にして言っていては、
説得力がないですしね。

Atsushi777

純粋に疑問なのですが、このケースで安全のため括弧を書く方々は、
たとえば、switch文はbreak;を忘れたら困るから使わないとか
そういうことまで考えるのでしょうか?
# どう考えても、こちらの間違いのほうが起こりそうですが。

ちなみに、括弧を書くか書かないかはスタイルの問題だと思っていて、
私は書かないですが、書く人がいてもそれはそれでいいです。

ただその理由が「安全のため」というのにものすごくひっかかっています。
安全のためにコードがどこまで冗長になっていくのかはわからないのですが、
一定の程度を超えてしまうと、それが保守しやすいとはとても思えないのです。

# 「安全のために」ちゃんと動いているコードをいじらないようにするため、
# コピー&ペーストして別関数をつくり、手直しする人がいました。
# どことなく、そういうところまで発展しそうな感じがして…。

riki

私も括弧をつける派です。

ちなみに、私は・・・
他の人が見た時に読みやすい場合はカッコイイ
読みにくい場合はカッコワルイ
って感じですね。
# 今回でいうと1行に2つの処理を書くと読みにくいからカッコワルイ。

あとは、昔コンパイラのバグってものに出くわして事があるので
省略できても省略しない。ってのあるんですが。

ひでみ

こんばんわです。ひでみです。
たくさんのコメントありがとうございます。

まりもさん。

> ちなみに、私個人の美的感覚で言うと、「カッコなし」は美しく「ない」とおもいます。

私の感覚で言うと「カッコつき」は「かわいい」と思います。
なんかこう、くるまれてる感じがかわいい。
女性の「かわいい」表現にアレルギー気味な男性が多いことは知ってますけど(苦笑)。


Atsushi777さん。

> 純粋に疑問なのですが、このケースで安全のため括弧を書く方々は、
> たとえば、switch文はbreak;を忘れたら困るから使わないとかそういうことまで考えるのでしょうか?

私自身は、それでコードがすっきりするのならswitch文も使います。
最初にcaseとbreak;を書き並べて、その後で中身を書き入れていく、ということはやりますけど(これならbreak;を忘れる可能性はかなり減ると思います)。
あと、あえてbreak;を使わないで下のcaseに落とす場合は、一応break;を書いたうえでコメントアウトします。意図的にはずしているということを明示するためです。
まあ、あえてbreak;をはずすって手法自体はめったなことじゃ使いませんけど(だったらif文使え、と)。

> ただその理由が「安全のため」というのにものすごくひっかかっています。
> 安全のためにコードがどこまで冗長になっていくのかはわからないのですが、
> 一定の程度を超えてしまうと、それが保守しやすいとはとても思えないのです。

確かに、程度を超えてしまうのは問題だと思います。
守りをかためすぎて保守性を失うのでは本末転倒です。
でも、カッコ一組分くらいならたいして冗長にはならないですし、if内(forやwhile等も同様ですが)に命令を付け加えるという修正はよく発生します。それに、カッコが抜け落ちているだけのバグは意外と発見しにくいんです。
玄関ドアに鍵をかけるのは普通で、「用心深い人」なら鍵を2、3個にするかもしれない。でも、10個もあったらさすがに「変わった人」だと思われます。
カッコをつけるのはせいぜい「用心深い人」ですむレベルだと思うんですが。

> # 「安全のために」ちゃんと動いているコードをいじらないようにするため、
> # コピー&ペーストして別関数をつくり、手直しする人がいました。

ファイルごとコピーしてバックアップとして保存しておく、ということはたまにやりますけど、手直ししたものと手直し前のものをクラス内に混在させているとしたら、かなりややこしいことになりそうですね。
監視カメラをつける人レベルとでもいうんでしょうか……。


rikiさん。

> あとは、昔コンパイラのバグってものに出くわして事があるので
> 省略できても省略しない。ってのあるんですが。

カッコがあるのとないのとでは違う動きをするコンパイラがあったということですか?
それはきいたことないです。こわいっ。

riki

ひでみさん。

>カッコがあるのとないのとでは違う動きをするコンパイラがあったということですか?

いえいえ。さすがに括弧ぐらいじゃ。
その時はまったく別の問題でしたが、コンパイラのバグだってありえるからちゃんと書くということを意識しているって感じです。

ちなみに、その時は普通にコンパイルすると問題ないけど、最適化オプションをつけてコンパイルすると不思議な動きが出てきたというパターンです。

ひでみ

こんばんわです。ひでみです。
rikiさん。さっそくのお返事ありがとうございました。

> いえいえ。さすがに括弧ぐらいじゃ。
> ちなみに、その時は普通にコンパイルすると問題ないけど、
> 最適化オプションをつけてコンパイルすると不思議な動きが出てきたというパターンです。

そんなわかりやすいバグがあるコンパイラがあるのか? とか思っちゃいました。はやとちりですみません。
私は、特定の標準関数を数十回連続してcallすると落ちる、という問題に遭遇したことがあります。

山男

if文の後の括弧ですが、省略が許されてるのではなく、ひとつの文がくるように定義されているだけです。
括弧をつけた複文もまたひとつの文となるということです。
省略が許されているという認識が間違っていると思います。

山男

ちなみにこういう場合、自分は必要なければ書きませんね。
規約があれば従わざるを得ませんが、正しいとも思えません。
結局こういうことを言うのは、自分のやり方を通したい人で
自分のレベルに合わせろと言ってるようにしか思えません。

あと、この件で、シンタックスシュガーとか言っている人がいるようですが、それとは違います。

undo

>自分のレベルに合わせろと言ってるようにしか思えません。

チームでプログラムを書く場合には、低いレベルに合わせるべきだと思います。そして、コードの書き方は揃えるべきです。そうしないとコードレビューもまともにできない。
型だけでバグを未然に防げるのであれば安いものです。その分、コードレビューやらUTやらを手伝わされる手間が減るのですから。

結局は、マルチスレッドで動作していることをきちんと考慮できているプログラムを書ける奴が少ないので、コードレビューに時間がかかるんですがね。シングルスレッドのプログラムもまともに書けない奴がチームに居る以上は「そいつのちょっと上」に合わせるしかありません。そうしないのであれば、できる奴一人の戦力を捨てて、そいつの人身御供に出すしかありません。
チームのみんなができる奴だったら、こんな些細な問題はどうでもいいんじゃないですかね?そういう恵まれた環境で仕事したいものです。

ひでみ

こんばんわです。ひでみです。今日はちょこっとだけ。

undoさん。

> チームのみんなができる奴だったら、こんな些細な問題はどうでもいいんじゃないですかね?

できる人でもできない人でも、人間である限り必ず間違えるもんだと思ってます。
それ以外の意見は激しく同意します。

山男

べつに規約を作ることに反対しているわけではないです。
が、「省略が許可されている記述」とか言ってる人の真似して
みんなでバカになればいいという発想には同意できません。

そもそも、括弧がどうこうより字下げのほうが重要なのに、
そこをあえて無視しているし、
そういうのも最近の出来のいいエディタでは間違える事もあまりないでしょう。

実際、自分ではここで述べられているような事で困ったことはありません。
昔は、x == NULL と書くな NULL == x と書けとか色々な事を言う人がいましたが
20年くらい前の感覚に感じます。

東京雄猫

意味論を考えれば、1行は複数行の特殊な形態でしかなく、複数行を書くときにはカッコが必要だという言語ならば、一行でもカッコはつけるべきで。
一行だからカッコをつけないというのは、例外事項を使用してでも楽な書き方をする事にしかなり得ませんから、基本はカッコ付けるべきでしょう。
誰がみてもすっきりしてるプログラム、メンテナンスしやすいプログラム、というのは、機械が処理するときにも処理しやすい、例外事項のすくないブログラムでしょうからね。
そう考えれば、省略はどちらかといえばスクリプト文化こらきたものでしょう。
また、ブログラムが画面に入りやすいからというのは、コードの問題というより開発環境の問題。
エディタが自動補完するから関数名はわかりやすくといっている時代にはマッチしないのて、老眼鏡をかけることをオススメしてください。

これはコンパイラ作るぐらい言語の意味論を勉強すれば自明だと想うんですけどね。
最近はあんまりそんな人いませんからねぇ。

余談。
定数を左辺に書くのは、数学的表記とも合致します。
英語の表記が左辺から右辺に流れていくことを考えると、左辺に定数が正しいでしょう。
バグも少なくなるしね。

utg

ひでみさん 初めてコメントさせていただきます。

今回の件に関し、ひでみさんのご意見は至極まともであり、
大げさに言えばフェイルセーフの考え方を、同僚の方がご存知無かったのかとお思います。

理論的なこと当たり前のことが、共通認識として広がることは非常に有意義なことですので今後もブログでの楽しいご指摘楽しみにしています。

aetos

言語規格的には、かっこをつけない場合も、{} で囲んだ複数の文がぶら下がる場合も、ひとつの文がぶら下がっているという認識なんですね。
でも俺には、{} で囲んだものが「ひとつの文」に見えない。これは感覚の問題だから、説得されてもどうしようもない。

それはそれとして、

> 意味論を考えれば、1行は複数行の特殊な形態でしかなく、複数行を書くときにはカッコが必要だという言語ならば、一行でもカッコはつけるべきで。

は容易に反論できますけどね。
そもそも問題は「1行か?」ではなく「1文か?」です。C はフリーフォーマットだから行数は関係ない。
で、「{} で囲んだものは1文の特殊な形態でしかなく、1文を書く場合にはカッコが要らない言語であれば、原則としてカッコは要らない」とも言えます。

また、「{} で囲んだものは1文」であるならば、「1文でも必ず {} で囲む」は無限ループを引き起こします。

ひでみ

こんばんわです。ひでみです。
私の知識不足で少々、混乱を招いてしまっているようです。ご不快な思いをさせてしまっていたら申し訳ありません。

けれど、開き直るな、と言われるのを承知で申し上げますが、私が100%正しい必要はないと思っています。
ここはプログラミング言語について教えるための場ではなく、私はプログラマとしてこんなことを考えているんだ、ということを伝えるために、エンジニアライフさんからお借りしている場なんですから。
私が間違っていたり、誤解を招く表現があった場合は、今回のように皆様がサポートしてくださいます。
私が持っていないさまざまな考え方を示して、コラムを補完してくださいます。
本当に本当に感謝しております。
最初っから他人にあまえるのもどうかと思いますけど、すべてを完璧にしなければ、なんて思っていたらこんなコラムこわくて書いていられません。
そんなわけで、これからもいろいろと間違えたり、うっかり感情的になったりすることがあるかと思いますが、その時はご指導のほどよろしくお願いします(←やっぱりあまえてるし)。

私はC言語を先輩から教わりましたが、今回の件は「省略」で覚えて今までやってきて、実際、それで問題が発生したことがないので、その解釈で覚えても問題はないと思っています。
しかし、「厳密にいえば省略ではない」というご指摘をいただいて、いろいろと認識を新たにするところがありました。
インドリさんに教えていただいたsyntax-sugarについても、知らなくても別に困ったことは発生していませんでしたが、調べてみると、なるほどこのことを知っていればいろいろなことを理解しやすくなるなあ、と感じます。
様々な知識や見識をただでちょうだいしていて申し訳ないんですけど(基本的に、知識に対しては報酬を払うべき、という考えなんですが)。
こういうことを知らなくてもプログラムは書けてましたけど、好きな人(?)の知らなかった側面を知ると、新鮮な気持ちになれるもんですよねえ。楽しいなあ。

とりあえず、たかだか括弧にこだわるプログラマが大量にいることがわかって幸せです(笑)。

Atsushi777

> とりあえず、たかだか括弧にこだわるプログラマが大量にいることがわかって幸せです(笑)。

私の場合はむしろ逆で、たかだか括弧くらいでコードが安全に傾くと無批判に考えているのが
気にかかっているだけです。
# それを気にするくらいなら、switchは使わないでしょう?
# switchは平気なあたり、実は安全なんかどうでもよくて、
# 自分のスタイルを肯定したいだけなのでは?

「省略」で覚えているということは、CやC++を正しく知らないということですよ?
正しく知りもしないのに、問題がないと思えるのはなぜですか?
今まで問題が発生していないから問題ないなんていうのが
プログラマの姿勢とはちょっと信じられません。

このケースで括弧をつけるつけないはスタイルの問題としては理解しますが、
括弧をつければ安全側に傾くというある意味での思考停止は、
やはりあまりよいものではないというのは、
こういうところに見え隠れしているように思えます。

山男

東京雄猫さんの意味論とやらは間違っています。
みんなざっとでもいいからCのBNFを見たらいいと思いますよ。

Atsushi777 の意見に同意します。

結局C自体の理解がかなり甘いので、おっかなびっくりやってるだけに思えます。

render

東京雄猫さん:
> 定数を左辺に書くのは、数学的表記とも合致します。
比較演算子の「数学的表記」が何か分かりませんが、方程式では、変数を左辺に、定数を右辺に書きますよね?
> 英語の表記が左辺から右辺に流れていくことを考えると、左辺に定数が正しいでしょう。
表記が左辺から右辺に流れていくことから「左辺に定数が正しい」をどのように導出したのか分かりませんが、比較演算子式を英語の文章にしてみましょう。
変数と定数の、比較演算子における演算のsubjectは、変数です。変数「が」、ある定数「と」等しいかどうか、というのが式の意味です。これを英語で書くなら、
"variable equals to 1"
となるでしょう。この文章を素直に比較演算式に直すのであれば、
variable == 1
ではないでしょうか。

比較演算式において、左辺に定数値を置くことは、バグを発見しやすくなるという人もいますが、以上の通り意味論的には定数値は右辺に置くべきであることが分かります。式の意味を把握しやすくなるため、デバッグやコードレビューにも役立ちます。また、最近の(ここで最近とは、遅くとも2003年以降を指します)のコンパイラでは、if文やwhile文の条件で代入が行われていると、警告を発します。以上より、=と==のタイプミスについて気をつけたいのなら、左辺に定数値を置くのではなく、コンパイラに警告させるべきでしょう。

aetos

> 自分のスタイルを肯定したいだけなのでは?

俺はそうです。それでいいじゃないですか。

len

>正しく知らない
>理解が甘い

私のような新米には耳の痛いお言葉です。
常に学習あるのみと、身の引き締まる思いです。

私は、煉さんの

>例え1行でも、後で処理を追加する際に括弧忘れのバグがおきることを警戒しています〜(以下略)

のケースと同じことを体験したので、「括弧=安全対策のひとつ」として考えることは間違ってないと感じました。一意見として。

ひでみ

こんばんわです。ひでみです。
昨日、コメント返しを書きそこねてましたので、ちょっとさかのぼります。
遅いうえに簡単にすませてしまっててすみませんです。


山男さん。

> 「省略が許可されている記述」とか言ってる人の真似して
> みんなでバカになればいいという発想には同意できません。

どこをどう解釈して、上記のような発想をしている人がいる、とお考えになったのかがわかりません。
省略が許可されている記述とか言ってるバカな人=私、という解釈をするとしても、私は、私の真似をしろなどとは言ってなくて、私はこう考えている、と言っているだけです。


東京雄猫さん。

> 意味論を考えれば、1行は複数行の特殊な形態でしかなく、
> 複数行を書くときにはカッコが必要だという言語ならば、一行でもカッコはつけるべきで。

「1行は複数行の特殊な形態」という発想も私の中にはありませんでした。
いろいろな捉え方があるものですねえ。


utgさん。

> 理論的なこと当たり前のことが、共通認識として広がることは非常に
> 有意義なことですので今後もブログでの楽しいご指摘楽しみにしています。

ありがとうございます。
有意義なことが書けるかはわかりませんが、今後ともおつきあいいただけるとうれしいです。


aetosさん。

> 言語規格的には、かっこをつけない場合も、{} で囲んだ複数の文がぶら下がる場合も、
> ひとつの文がぶら下がっているという認識なんですね。

括弧でかこむことにより一文になる、という解釈であってますか?

> また、「{} で囲んだものは1文」であるならば、「1文でも必ず {} で囲む」は無限ループを引き起こします。

一文のものをさらに一文にする、ということは、二重にすることにはなっても、無限ループにはならないような気がするんですが。


Atsushi777さん。

> 「省略」で覚えているということは、CやC++を正しく知らないということですよ?
> 正しく知りもしないのに、問題がないと思えるのはなぜですか?

言語はあくまでも言語なので、相手(=コンパイラ)に意図したとおりに命令が届けばいいものと考えています。
ですから、命令を確実に届ける方法さえ知っておけば問題はないと判断しました。
括弧を付け忘れることによって、命令が正確でなくなることの方を、私は問題視します。


renderさん。

> 最近の(ここで最近とは、遅くとも2003年以降を指します)のコンパイラでは、
> if文やwhile文の条件で代入が行われていると、警告を発します。

私が使っていた範囲では、Cコンパイラにそのような警告を発する機能はついてませんでした。
10年以上も前の話なので「最近」とは言いがたいですが。


lenさん。

>>> 正しく知らない
>>> 理解が甘い
> 私のような新米には耳の痛いお言葉です。
> 常に学習あるのみと、身の引き締まる思いです。

キャリアが20年を超えても、あっちこっちから怒られている自分がいます(苦笑)。

まりも

後半になるとカッコ反対派が増えてきたような気がしますが。

Cを習って数日目にはもう、
一文が本来の文法で、
それを複数に拡張するのがカッコなのだな、
と気づいていましたが。

でもカッコは付けることにしてます。
別に理解度の差ではないと思う。

たんに、保守性を上げるためにできることがあるなら、
できることはすべてやるというだけのことではないかなあ。

まりも

人が何を美しく感じるかを考えてみると、
シンプルなものを美しく感じるという面があるように思えます。

数学とか物理とか、
あとプログラミングのときなんかは、
その人間の習性をうまく使っているのではないでしょうか。

シンプルかどうかを判別するよりも、美しいかどうかを感じるほうが、
労力が少なくて済みますから。

プログラム中はただでさえ考えることが多いのだから、
瞬時に分かる方法があるなら有効活用すべき。

なのですが。
まあ感じているだけですから、勘違いも多いわけで。
自分が慣れているほうが美しく感じてしまうこともあれば、
好みの差で意見が分かれることもある。

だからまあ、必要な時には、
きちんと判断することも必要になるわけです。


ということで、
カッコがあるほうがカッコイイというのも十分にありだが、
それだけじゃなく保守性もきっちり判断すべきこともある、
ということですね。


なお、かわいいかどうかをプログラム中に重視すべきかどうかは、
考えたことがなかったです。
男性にしてはそのへんの感性はあるつもりではあるが。

考えてみるとすると。
ただでさえたまる傾向がある仕事中のストレスを少しでも何とかするためなら、
案外重要なのかもしれませんねえ。
かわいさも。

ひでみ

こんばんわです。ひでみです。

まりもさん。
きれいにまとめてくださってありがとうございます。

> なお、かわいいかどうかをプログラム中に重視すべきかどうかは、
> 考えたことがなかったです。
> 男性にしてはそのへんの感性はあるつもりではあるが。

私の「かわいい」のセンスは相当変わってると友人達に言われます。
バイナリツリーの絵を初めて見た時に「かわいい」と言ってひんしゅくを買ったぐらいのセンスです。
でも、波カッコ({})はカッコの中でも格別かわいいと思います。

もにゃら

ひでみさんのポリシーには、さらに良いことがあります。

変更前のコードが、
if (nantoka)
return;
だったときに、1文追加する修正が必要になった場合は

if (nantoka) {
pos++;
return;
}
のようになります。

これはソース管理ツールの差分としては、
! if (nantoka) {
+ pos++;
_ return;
+ }
となり、論理的な差分は1行なのに、物理的には3行の違いになります。
最初からカッコつきなら、本当に1行だけの差分です(3倍!)。

1行いくら の仕事なら逆にこっちの方が良かったりするんですかね…w

もう少しまじめな話としては、ifの条件文が複雑な式だったりするときは、1行目の差分が本当にブレース1個なのか、
一般的な行志向の差分表示では注意深く確認しないと、エンバグの見落としの危険が生じます。

1人での開発と違ってチーム開発ならこの辺を考えても安全な方に振っておきたいですよね。

ひでみ

こんばんわです。ひでみです。

もにゃらさん。

> これはソース管理ツールの差分としては、
> ! if (nantoka) {
> + pos++;
> _ return;
> + }
> となり、論理的な差分は1行なのに、物理的には3行の違いになります。

バージョン管理のことまで考えるとわっ。その発想が出てこなかったことがくやしいです(笑)。

Atsushi777

しかし、たとえば、
if (nantoka)
+{
+ pos++;
_ return;
+ }
ならどうってことないのでは? < 差分

もにゃら

Atsushi777さんの仰るとおり、例示したコード片では
差分はどうってことないと思います。
ただ、ぼくが言いたかったのはリビジョン間の差分に論理的な変更
(pos++の行)以外の差分が入っていると、気持ち悪いですよねって
ことです。
また、この手のある意味余計な差分はdiff出力の増加を引き起こすので、
差分の一覧性が悪くなるという弊害もあると思います。

Jitta

お初です。
つい最近、こんな間違いをしました。

修正前:
if (condition A) {
} else {
}

こう書いたつもり:
if (condition A) {
} else if (condition B) {
} else {
}

実際に書いたこと:
if (condition A) {
} if (condition B) {
} else {
 condition A がここも実行してしまうバグ
}

 コードを追いかければすぐにわかるけど、焦っていると気がつきにくいorz

elese if も、else で改行っすかね?(苦笑)

ひでみ

こんばんわです。ひでみです。

Jittaさん。はじめまして。

> 実際に書いたこと:
> if (condition A) {
> } if (condition B) {
> } else {
>  condition A がここも実行してしまうバグ
> }
> elese if も、else で改行っすかね?(苦笑)

if (condition A)
{
}
派なら回避できたかもしれませんねえ、案外(笑)。

「この1行だけしか目に入ってなかったのか」って数日前の自分を問い詰めたくなるようなバグってありますよね。
ことにコード修正時にこの手のミスが多いような気がします。
すでに動いてるコードだという安心感があるから、ターゲットの行しか見えなくなるんですかねえ。

Atsushi777

> ただ、ぼくが言いたかったのはリビジョン間の差分に論理的な変更
> (pos++の行)以外の差分が入っていると、気持ち悪いですよねって
> ことです。
括弧くらいで論理的な変更がどうこうで気持ち悪いなどと言うのであれば、
変更の結果、他と同じ処理になる部分を関数に切り出して、
両方から呼び出すようにする、なんてのはもってのほかですかね?

私はこういうことを必要以上に気にするのはむしろ害悪だと思います。

東京雄猫

行と文を取り違えてましたね。
すいません。
行を文に読みかえてください。

以下、後学のために。
長文失礼します。

意味論と構文は意味論を上位に置き、次元を別けて考えなければならないでしょう。
言語構文は、構文要素の意味の上に構築される物で、構文上許される表記は意味に影響を及ぼさないものであるはずです。
(そうじゃない言語もあるでしょうけどね)
C言語においても、一文のみがカッコを付けなくてもよいという特性を持つため、複数文は一文の特殊な形態とはなり得ませんが、これは複数文、一文それぞれに用いられる式文の意味を変えるものではありません。
そしてそれゆえに、一文は複数文が持つ特性を全て保持するため、複数文たりえます。

構文の拡張による機能の追加では、その拡張が基本的な構文要素の意味に影響を与えない事に注意する必要があります。
そうしないとその言語で過去に書かれたブログラムの動作が変わってしまいますし、新規の言語でも、たとえば文の意味をかえる拡張ならば一文目の1+1と2文目の1+1の結果が変わるとか、とても書きにくい言語になってしまいます。
そして、覚えのかぎりでは、Cの構文もその原則乗っ取っていたと思います。

数学的表記と書いているものですが、あれは定義文ではなく比較文のお話なので、式全体の真偽を取るのが目的ですから、本来の意味としては両辺ともに定数と取るのが正しいですよね。
なぜならば、比較文は定義の変更は目的としておらず、その時式中で使われる変数は単なるラベルの意味合いであるはずですから。
また、数学上「1」等の数も、値域の概念を考えれば、ラベルでしょう。
たとえば1が2より大きい差分としての1だった場合実体は3ということになり、「この1は3だ」としても真ですよね。(このときの1は3と次元が違います)
その上で、数式で定義を右に持ってくる表記法を考えれば、検証したい内容を右辺に持ってくるのが妥当と考えられ、
それを推進すると自動的に左辺が固定値になることが多くなるかと思います。

意味論上は数の概念では1が数直線上の通過点でしか無いことや、全ての要素はラベルであり実体は語り得ないものであることを意識しなきゃいけないと思いますけど、どうしてもとらわれますよね。

っと、人様のブログですし、荒れると思ったので時間を置きました。
自分が慣れた書き方でバグが出にくければそれでよし・・・なんですが、知識として知っておいて損ないし、コーディングルールで縛られたときに他の考え方を受け入れやすくするための道具にそれら知識が使えれば儲けもんでしょう?、ぐらいの感覚で書いてます。

FPGAで8ビットCPUぐらいデザインできて、それ用のコンパイラ自分で書けてぐらいになって始めて学術的に語れるレベルの知識になるんだと思って、自分でも一生懸命勉強しましたけど、業界歴が長くなるにつれ、そんな事まじめに勉強してもついてこれない人が増えるだけであまり意味が無いと諦めるようになりました。
俺にとっては結構悲しい事です。

ひでみ

こんばんわです。ひでみです。ちょっとごぶさたしております。

東京雄猫さん。

丁寧なご説明ありがとうございます。
私にない視点を持ち込んでいただけて、とてもありがたく思います。

> 数学的表記と書いているものですが、あれは定義文ではなく
> 比較文のお話なので、式全体の真偽を取るのが目的ですから、
> 本来の意味としては両辺ともに定数と取るのが正しいですよね。

この考え方は目からウロコでした。
それで何が変わるってことはないような気がしますが、単純に「おもしろい!」って思いました。
これがウワサのアハ体験というやつでしょうか(笑)。

> 学術的に語れるレベルの知識になるんだと思って、
> 自分でも一生懸命勉強しましたけど、業界歴が長くなるにつれ、
> そんな事まじめに勉強してもついてこれない人が増えるだけで
> あまり意味が無いと諦めるようになりました。
> 俺にとっては結構悲しい事です。

プログラミングを学術的に考えてみよう、と考えたことがないです。
すみません……。
けれど、それを極めようとしている人がいないってのもさびしいかなあ、と思います。
自分がやってないことを人に押しつけるようで恐縮ですが。

BUS

{}はライターさんの意見に賛同。

でも、男とか女のくだりは要らないよね。
性別逆だったら、フェミニストが「セクハラです」とか言い出す文章だ。

インドリ

わぉっまだ続いている・・・

東京雄猫さんへ
>FPGAで8ビットCPUぐらいデザインできて、それ用のコンパイラ自分で書けてぐらいになって始めて学術的に語れるレベルの知識になるんだと思って、自分でも一生懸命勉強しましたけど、業界歴が長くなるにつれ、そんな事まじめに勉強してもついてこれない人が増えるだけであまり意味が無いと諦めるようになりました。
俺にとっては結構悲しい事です。

あきらめちゃ駄目。人様が無知であろうとどうでもいいことです。
私はOS実装からシステム構築まで全てを修得するべく奮闘しております。
ですからあきらめないで下さい。
ちなみに、私はまだ意味論まで着手できていません。
でもゆくゆくは、意味論やラムダ計算やπ計算も学習する予定です。
私は一応コンパイラもOSも不完全ながら作れます。
最近はそれだけでは飽き足らず、より深く学ぶためにCPUの作り方や数学にも手を出しています。
お互い頑張りましょう。

焼きそば

このレスの長さが全てを物語っていますよね。
> 傍目から見ると宗教論っていわれても仕方がないですね。
お金もらってプロでやっている以上、品質の担保と納期は
絶対におろそかにできないですよね。
だからこそ、事前に打てる策はなんでもやろうとするのだと思います。
たとえ、括弧いっこでもね。

お浜

なんだコリャ?
括弧付ける云々より、ステートメントで改行しない方がいかがなものかと。

それとC,PHP,Javaしかやったこと無い人はPascal,Ruby,Pythonなどやってみるよろし。コーディングスタイルの考え方が変わる事請け合い。LISP系列もいいね。

トロピカーナ

何のためにプログラム書いてるかが大事だと思います。
仕事なのか、趣味なのか、研究なのか、目的や環境によって、正解は違うような気がします。

自分一人しか見ないなら自分の好きなように書けばいいし、大規模プロジェクトなら、どう書くかよりもどう統一するか(FindBugsとかcheckstyle使ったりして)が重要です。

また、保守性ももちろん重要ですが、もし誰かからお金をもらってソースコードを書くのなら、その誰かが「カッコをつけるかつけないかの判断」を本当に望むかどうかだと思います。

F論太

楽しませてもらいました。

「わたしよりもバグの発生率が低くなったら、言うことききます!」

上記の台詞に自分の書いたコードに対する自負が感じられました。
また指摘した相手に対して自分より力量ないやつに言われたかない!
という気持ちが感じられました(笑)

こういう類の論争を宗教論争というのも初めて知りました。

開発対象としているものが何であるかによりコーディング規約も
プロジェクト毎に出入りがあるとは思いますが、上記のケースの
場合、規約になければ個人の裁量の範囲で済ますしかないのでは?

あなたの根拠とする保守性については多くの事例から結構な説得力
はありそうな気はします。
先日たまたま興味があって「品質向上によるコスト削減」に参加した
のですが、無料のセミナーだったので静的解析ツールのお話が中心
でした。
静的解析ツールでは{}つきでないと警告を出すみたいです。。。
経験則からくる「こだわり」については共感を覚えます。
頑張ってプログラマ道を極めてください。

aetos

> 括弧でかこむことにより一文になる、という解釈であってますか?

だと思います。

> 一文のものをさらに一文にする、ということは、二重にすることにはなっても、無限ループにはならないような気がするんですが。

屁理屈なので無視して頂いても結構です。
例えるなら「ごみは1つでもごみ袋に入れる」「ごみの入った袋はそれ自体がごみである」みたいな。

avevil

こういうの、読んでておもしろいですねぇ。
私的には、皆さん一理あると思います。個人的には「涼しければ」派です。

昔は、くどい書き方をすると「COBOLみたいなC」などと言われたものですが、ハンガリー記法などが一般的になり始めて以降、いつの間にか「冗長な記述=ミスが減る」という認識(ある程度までは正しい)が「正義」になってしまい、そうでないものはすべからく「悪」になってしまった気がします。(ちょっと寂しい)

かつて、いわゆる「C言語らしいコーディングスタイル」には、ある意味保守性など無視した部分があって、そんな部分もひっくるめて「Cはかっこいい」言語だったのですが・・・・

勿論、保守性は最重要事項ですよ。
でも、括弧でそんなに変わるものなのかなぁ?

ひでみ

こんばんわです。ひでみです。
このコラムもついに落ち着いたかと思っていたら再燃してますね(苦笑)。
あいかわらずコメント返しが短くてすみませんです。


インドリさん。

> わぉっまだ続いている・・・

まだまだ続いてますよ~(笑)。


焼きそばさん。

> このレスの長さが全てを物語っていますよね。
> 傍目から見ると宗教論っていわれても仕方がないですね。

こんな細かい話がここまでふくらむものだとは、私も思っていなかったです。
プログラマになろうかと考えている学生さんたちが「カッコぐらいでこんな細かいこと言われるなんて、プログラマの世界ってコワい」とか思っちゃったりしないか、とまで考えちゃう始末です(苦笑)。


お浜さん。

> なんだコリャ?
> 括弧付ける云々より、ステートメントで改行しない方がいかがなものかと。

正直「前スレ読め」と言いたいとこなんですけど、この長さになってくると言いづらいですね。
コラムとして読みやすいように改行は省略してあります。
カッコがテーマの話なんでたいして気に留めていなかったんですが、こんなにひっかかる方が多いとは予想外でした。


トロピカーナさん。

> 自分一人しか見ないなら自分の好きなように書けばいいし、大規模プロジェクトなら、
> どう書くかよりもどう統一するか(FindBugsとかcheckstyle使ったりして)が重要です。

「どう統一するか」は確かに重要ポイントだと思います。
私はコードスタイルの違いをおもしろがるクチなので、統一されていない方が飽きなくていい、くらいに思っていたんですが、人によってはものすごくストレスに感じるようですので。


F論太さん。
少しでもお楽しみいただけたのなら幸いです。

> 静的解析ツールでは{}つきでないと警告を出すみたいです。。。

最近の解析ツールはそういうところまでチェックするんですか。
ツールなんてほとんど使ったことがないオールドC/C++使いとしては、うらやましいやら、自分の時代遅れっぷりが気になるやら。


aetosさん。

> 屁理屈なので無視して頂いても結構です。

了解しました。無粋なことを申しました。


avevilさん。

> 勿論、保守性は最重要事項ですよ。
> でも、括弧でそんなに変わるものなのかなぁ?

それはデータがないのでなんとも言えないですね。
このコラムで例としてあげたバグを発見した時に「いつか私もやりそうな気がする」と思ったので、その直感を信じてる、というのが根拠といえば根拠です。

ちぃ

ひでみさん、はじめまして。
みなさんも、はじめまして。

とおりすがりの「ちぃ」と申します。
どこかからここに迷い込んでしまいました。

でも、とぉーっても愉しく拝見させていただきました。読破です(笑)。
ひでみさんの返信コメントに愉快すぎて、抱腹することもありました。
物の見方、受け止め方、考え方、切り捨て方、色々あるのだなぁと。

こちらの皆様は本職の方たちなのですね。

私は仕事で使う自分用の小品を作ることがほとんどです。
私のほかにはスクリプトも含めてプログラムと呼べるものを書く人はいません。

ひでみさんの立ち位置とはまったく異なる場所です。
それでも、フェイル・トゥ・セイフを心がけています。
そういう意味で、読みやすさと拡張性、そして、外来ノイズ(DLLなどの仕様変更など)も考えて、冗長性のある記述になります。
もしかしたら、他人が見ること、むしろ、未来における拡張のための自分用です。

会社ではウィンドーズパソコンを使いますが、開発環境と呼べるものはなく、
強いてあげれば、マイクロソフトオフィスがあることくらいです。
基本的に、集計とデータ変換が主ですので、現場での試行錯誤と万が一の障害対処を考慮して、とりあえず、VBAで動くものを書いています。
他人に提供することもありますが、専ら自分用であるが故、ドキュメントは作らないので、忘れてはならないことのみコード内にコメントを書き込んでいます。
構文的には省略できるものでも、できるだけ省略しないで記述しています。
省略は、時として、省略時の振る舞いが改変されることがあるからです。
IDEがあっても、それだけに頼りきりにはならないで、自分のスタイルで書いています。昔は、IDEはなく、普通のテキストエディターでガリガリ書いていましたので。
特にインデントは重視します。開発言語を問わずに。
引数や入れ子構造が判別しづらいと、保守も拡張もできませんので。
VBAで書いているときも、関数定義や関数参照でも引数をその数分、
次行への継続を表す" _"を付与して、強制的に改行するほどの懲りようです。

さて、本題である例題の答えは、私の場合は波括弧ごとインデントです。
本職の方から見ると気持ち悪いかな?

if (buffer == null)
  {
  return;
  }

ここに、私個人が感じたことを書きとめておきます。

お浜さんのおっしゃったことに賛同します。私個人としてもお勧めです。
特定のものが主であるからこそ、その他のものにも触れることで、
いま、主としているものを再認識できることでしょう。

東京雄猫さんの視点と次元による考え方もわかりやすく、好感を抱きました。


ここで、すこし、昔話をしましょう。

私が開発言語に触れたのは学生のころでした。
簡単に触れられるものは、アセンブラとフォートランくらいしかありませんでした。
Cに触れられる人は限られていました。

電算室と呼ばれる部屋にNECのNEAC50とNEAC30、
そして、周辺装置が何種類か、それぞれが単独の存在であるかのように、
鎮座していました。
世間はその先を行っていたようです。
時代的にはDECのpdpのほうが良かったのでないでしょうか。
パソコンの世界では、TRS-80が発売されたころです。
後輩のおもちゃになっていましたが。

まだ、このころのコンパイラには最適化のためのオプションはなく、
コーディングそのものが実行所要時間を左右しました。
アセンブラも同様です。
当時はアセンブラやコンパイラがどのような動きをするのかまで考慮して
コードを書いていました。

NEACのCPUのオーバーヘッドや待ち時間を減らすために、
数式の中で直値(値そのもの)が先にスタックに格納されるように、
数式内部の左側に記述し、続いて、直接参照や間接参照による参照値(ラベル)を記述していくように教示されました。

たとえば、 A+1 ではなく 1+A と記述する。

式は左側から右方向へ計算対象ごとに順次解析され、スタックと呼ばれるLILOの領域に格納されていたので、そのまま、演算ユニットに手渡せる直値の 1 を最後にスタックに入れてしまうと、一旦、それをどこか違う場所に保存し直さなければならない。
そして、その前にスタックに格納された参照値 A を直値に変換して、
今一度、スタックに戻し、
どこかに保存しておいた直値 1 を読み出し、演算ユニットへ渡す。
そして、スタックから参照値 A の直値を取り出し、
やっと演算できるといった具合です。

つまり、直値を左側に寄せないと、無用なアドレッシングが増え、
プログラムの実行所要時間が長くなるということです。

それから、十何年か経って、市井のコンパイラに最適化オプションがついたのですが、rikiさんも遭遇されたようにまともに使える代物ではありませんでした。

いまはこのようなことを意識しなくても、ひでみさんのおっしゃったように
コンパイラに何をしてほしいのかを正しく伝えることだけで十分なのですね。

この半世紀の間に、CPUをはじめとする装置関係だけではなく、開発環境もこれでどうだというくらい進化しましたね。
開発時の定数参照も常時接続状態のインターネットでサイト上を参照するように記述することで済ませられますよね。実際にそのように参照する、しないは別としても。

現在の恵まれた開発環境の中で、
冗長性がどうとか、
画面で1関数を見渡せるようにとか、
50行以内とか、 // (コーディングシートってまだあるのかな?)
コードの世代管理での差分とか、
なぜ、そんなに気にしなくてはならないのでしょう?
カタカナ読みとかも謂わんとしていることは解釈できるのですから、
汲み取ってあげればよいでしょう。

ましてや、Cはフリーコーディングですよね。

みなさんが、皆さんの感性と創造力を発揮して個性豊かな美しいコードを、
それでいて、誤認識されず、拡張時のフェイル・トゥ・セイフも視野に入れた、
完成度の高いプログラムを生成できると思います。

私はひでみさんの直感を信じて、ひでみさんのスタイルで良いと思います。
たった1組のかわいい波括弧で未来においても問題を起こさないはっぴぃなプログラムになるのなら、転ばぬ先の杖として大歓迎です。

ひでみ

こんばんわです。ひでみです。

ちぃさん。はじめまして。

> でも、とぉーっても愉しく拝見させていただきました。読破です(笑)。
> ひでみさんの返信コメントに愉快すぎて、抱腹することもありました。
> 物の見方、受け止め方、考え方、切り捨て方、色々あるのだなぁと。

ここのコメントを読破するのはかなり大変そうです。おつかれさまでした。
ところで、私、そんなに笑えるコメント返ししてますか?

ていねいなコメントありがとうございました。
なんだかとてもなつかしい単語がたくさん出てきて、昔のことをいろいろと思い出してしまいました。
オーバーヘッドがうんぬんかんぬん、というお話は、先輩方からきいた記憶があるんですが、さっぱり理解できてませんでした。
今ならもっと楽しく話しがきけると思うんですが、当時はとにかくちんぷんかんぷんで(苦笑)。

ムック

いろいろ盛り上がっているのを拝見させて頂いて私もちょこっと。

先にプログラムは、見やすく、小さめで、必要に応じて簡潔なコメントが
ついている事が基本と思っています。

そんな中で私の場合は、状況に応じてカッコを付けたり付けなかったりですが
基本的に他人にテストしてもらう前に、全ての関数は出来るだけ自分で
テストしますので大きなバグは余り外に出ません。
(最終的にはこのテストが一番重要かと・・・)

なので、見やすければ、どちらでも派です。

ただ、チームワークのやり方次第ではコーディングとテストが分かれている場合
そう言う訳にいかないでしょうがね。

HZ

コメント全部読ませていただきました。
私は括弧付ける派です。
「括弧付ける派のバカ」の様な書き込みがありましたが、
「括弧付けない派の人」は括弧が付いていた場合でも読めますよね?
「括弧付ける派のバカ」は括弧が付いていないと読めない可能性があるんです。
後からコードを触る人がそのバカかも知れない。
これだけでも括弧を付ける理由としては十分だと思いますけどね。
※括弧付ける人をバカにしているコメントではありません。

>あえてbreak;を使わないで下のcaseに落とす場合は、一応break;を書いたうえでコメントアウトします。
>意図的にはずしているということを明示するためです。
これは目から鱗でした。

ひでみ

こんばんわです。ひでみです。


ムックさん。

> 基本的に他人にテストしてもらう前に、全ての関数は出来るだけ自分で
> テストしますので大きなバグは余り外に出ません。
> なので、見やすければ、どちらでも派です。

そのプログラムのライフサイクルが閉じるまで、すべて自分で面倒をみられればいいんですけど、仕事でやっている以上、プログラムが他人の手によって修正される可能性があります。
そのためにも、間違った修正をされにくいコード、を書く必要があると考えています。


HZさん。

> コメント全部読ませていただきました。

本当におつかれさまでした。

caseとbreakの件に関しては、他人のコードを修正していた時に、意図的にはずしたのか単なる書き忘れかを判断するのにずいぶんと時間がかかったことがあって、それ以来、通常あるべきものがない場合は、ひとまず書いたうえでコメントアウトする、という書き方をするようになりました。
誤読されにくいコードを書くうえで、少しでも参考になったのなら幸いです。

cherry

ソフトウェアのライフサイクルでは、保守のフェーズが圧倒的に長くて
その間、修正もしくは流用する場面もあり、複数の人間がそのプログラ
ムを読む事になります。
私は、他人のプログラムを読む機会が多いのですが、だらだらと長いプ
ログラムは読みにくく、良く言われる「一つの処理は一目で見渡せる」
とありがたいです。
自分が書く場合は、極力プログラムが短くなる様、省略できる括弧は付
けない派ですね。

CMP

私は括弧つける派ですね。

経験上、条件分岐には修正が入りやすく、大抵1文でもいいだろって所から1文追加になっていくので。
メンテナンスをしているときなど、スコープ内変数で対応することもあり、最初から括弧付けとけと規約に追加させたりしてました。

昔は如何に少ないコーディング量でアプリを作るかってこともしていましたが、現実問題として、そんなコードは拡張性がまったくなく、作った本人でもメンテナンスできないんですよね(汗)。

通りすがり

私は省略したい派です。
つけても問題はないのですが
Pythonやってると
他の言語でも省略したくなる

通りすがり

いろいろ考えたけどやっぱり
C++とかだと省略しない方が可読性が増すかもしれません。
今日からかっこを省略しないようにします。

コメントを投稿する