- ベストアンサー
コーディング作法の異議あり
- コーディング作法ガイド[C言語版]の内容に疑問
- 「等しくなければ」の表現が分かり難い
- ゼロとの比較命令は無駄だと主張
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
まずこの作法が書かれている章のタイトルを確認願います。そこには「保守性」と書かれていて、章の冒頭には「保守性を維持し、向上させるための作法」とあるはずです。それに対してあなたの意見は処理効率の向上を意図しており、筆者の意図と異なる立場から当作法の批判を行っている的外れなものとなっています。 また、21-22ページの凡例によれば、この作法は「プロジェクトの特性に合わせて選択すればよいと思われるルール」となっており、採用しなくても問題は軽微なものとなっております。 ですので、あなたが個人的にコードを組む、あるいは、プロジェクトのコーディング規約を決定できる立場にあるのであれば、別にこの作法を無視してもかまいません。しかし、コーディング規約としてこの作法が採用されているプロジェクトで作業するのならば、あなたはこれに従うべきです。
その他の回答 (9)
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
No.4 です。 あ、だから、if(x) と if(x != 0) では全く同じコードを生成するコンパイラや、 ++k と k = k + 1 では全く同じコードを生成するコンパイラは、 「決して珍しくない」ということを認識しておけば、別にいいかなと。
お礼
回答有難う御座いました。
- wormhole
- ベストアンサー率28% (1626/5665)
>例えば次の2例は似ているけど、自分のコンパイラ結果を見るとコード量と速さが違います。 >do{ }while( --j ) >do{ }while( j-- ) 元の意味が違うのだからコードが変わるのは当然だと思うのですが・・・
お礼
回答有難う御座いました。
- Tacosan
- ベストアンサー率23% (3656/15482)
え? do{ }while( --j ) do{ }while( j-- ) って, 似てる? 表記こそ似てるけど, 動作は全然違うよね. そして, この場合に「j-- が正しいなら --j に直すのはただの馬鹿」ってことは常識だね. あと, 「突っ込むにしてもそんなささいなことを突っ込んでもしょうがないだろうなぁ」の裏には「もっと盛大な突っ込みどころがある」ことを示唆しているわけだが, わかってる?
お礼
回答有難う御座いました。
補足
Tacosan は此処でよく回答されている方で尊敬していたのですが、そんな言い方をされてショックだな。
- Tacosan
- ベストアンサー率23% (3656/15482)
うちの gcc だと if (x) と if(x != 0) で全く同じコードをはいてる. ついでにいうと ++K; と K = K+1; も全く同じ.
お礼
回答有難う御座いました。
- 正親町(@Ohgimachi)
- ベストアンサー率43% (110/252)
良いコーディングとは 作成者以外のプログラマーがデバックや修正をし易いコーディング の事をさします。 デバッグや修正の実作業においては、 ソースファイルの検索 というのが必須になります。 エディタまたはツール(awkなど)を使用する場合 正規表現で該当箇所を検索するのですが 簡単に検索可能であれば作業労力を減らすことができます。 質問の適合例では 変数xの0判定をしているコードを検索しようとすれば x [!=]= 0 と入力すれば、複数の判定も含めて確実に捕捉できます。 例 (x != 0 || x == 5) 不適合例のように記述してしまうと switch文のようなものも検索にかかるうえに (x || x == 5) のような文の検索に手間がかかることになります。 要約すると 判定文のコーディングを統一すると、機械的な検索の手間が減るということです。 if (x) のような記述は変数がbool型に統一するべきです。 瑣末のような話とか思うかもしれませんが こういう無駄な労力の排除の積み重ねが 納期の短縮、プログラムの品質向上に結びつくのです。 おまけ 変数の0判定は論理積(AND)以外にも 差(SUB)の演算も多用されます。 CPUによっては、データの移動のみでも フラグがセットされる機種(ARMなど)もあります。 どれが最適かはコンパイラに任せておけばよいのです。
お礼
回答有難うございました。
- D-Matsu
- ベストアンサー率45% (1080/2394)
既に同様の回答がありますが、xが論理型的扱い(0/0以外で判断)なら下を使いますし、数値扱い(任意の値で判断)なら上を使います。上の式は「特定の値(0)でない場合」を明確に示しているのでどこがわかり難いのかがわかりません。 あと「最適化しなかった場合のコード」を理由にするのはどう考えても不自然です。デバッグ中の動作検証用なら多少無駄コードが入っていても問題はないし、リリース版で最適化しない理由はありませんから。
お礼
回答有難うございます。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
直接の回答ではないですが、 > しかし最適化をせずにその意味のままコンパイルすれば、ゼロとの比較命令になる。 > メモリ使用量、速度の両方とも不利になると思います。 「最適化をせずに」というのが、どのレベルかによりますが、少なくとも、「最適化を禁止しない」という条件で、(デフォルトの状態で)コンパイルすると、 if (x != 0) を、if(x) と全く同じにコンパイルする処理系はそんなに珍しくないですよ。 最近は、最適化でコンパイラを出し抜こうとすると、最適化できずに遅い(大きい)コードになるというケースも、ままあるはずです。
お礼
回答有難う御座います。 この例だと、たぶんゼロとの比較命令には置き換わらないでしょう。 しかしプログラマの意思を尊重して、ゼロとの比較命令に置き換わるかも知れません。 短く速いコードにしたければ、if(x)の方が確実だと思っている訳です。 次の式は ++K に似ていますが、コンパイルすると違います。 K = K+1 自分のコンパイラー結果を見ると、++K ならマシン語のインクリメント命令になるけれど、K = K+1 は次のようになりました。 K は既にレジスタに在るとします。 ・Kを他のレジスタにコピーする ・コピーしたレジスタをインクリメントする ・そのレジスターをKにコピーする このような事が有るので短く速いコードにしたければ、コンパイラがどのように解釈してもif(x)の方が確実だと思っている訳です。
- Tacosan
- ベストアンサー率23% (3656/15482)
確かに何も書いてないからなんともいいにくいけど, 適合例/不適合例を見る限り「0 かどうかを調べる」ことを目的としているんだろうから「0 かどうかを調べる」べく等価判定するのは自然だと思う. もちろん, フラグとして (つまり「0 以外の値はなんであっても同じ」という状況で) 使うなら比較はしないけど, だとしたら「なんで例で使った値が 1 じゃなくて 5 なのか」がわからん. そもそも, こんなところで独白することに意味があると思えないし, 突っ込むにしてもそんなささいなことを突っ込んでもしょうがないだろうなぁ....
お礼
Tacosan 回答有難う御座います。ここで良く見かけますね。C言語には詳しそうですね。 >突っ込むにしてもそんなささいなことを突っ込んでもしょうがないだろうなぁ.... 些細な違いで、出来上がるコードが違うからです。 例えば次の2例は似ているけど、自分のコンパイラ結果を見るとコード量と速さが違います。 do{ }while( --j ) do{ }while( j-- ) --j ならば次の動作をします。jは既にレジスタに在るものとします。 ・jをディクリメントする ・結果、ゼロなら終了する j-- にすると次の動作をします。 ・jを他のレジスターにコピーする ・jをディクリメントする ・コピーしたレジスターの値を評価して、ゼロなら終了する だから私は、--jの方を使います。と言っても趣味でたまにいじる程度ですけどね。
- wormhole
- ベストアンサー率28% (1626/5665)
その本を読んだことないので、そこだけ抜き出されても答えにくいのですが 「xが0でない場合」という条件だったのであれば適合例の方で書きます。 不適合例の方だと「xが真の場合」と読んでしまいますので。 些細な最適化なんてコンパイラに任せちゃえばいいし。
お礼
こんな真夜中に早速の回答有難う御座いました。
お礼
回答有難う御座いました。 確かにあなたのおっしゃる通り、私の意図は短く速いプログラムに有りました。