C に記述標準を設けてバグの入りにくいコードを書けるようにという志で作られた MISRA C ですが、 関数の末尾以外の return を禁止するという誰得ルールを筆頭に使い物にならない制約が多すぎます。 役に立つところといえば、これをそのまま採用するところの技術力は信用できないという判断材料になることぐらい。
returnの場合は様々な要因が絡むからアレだけど, 似た例ではif文とif句の違いがあります. if(a){
x = A; }else{
x = B; } とあるものは, x = if(a) A else B あるいは, x = a?A:B; の方が大抵の場合は見通しが良いですよね. 文頭から, 「あ, xになんか代入すんだな」っていうことがわかります.
MISRA C という失敗 (スコア:1)
C に記述標準を設けてバグの入りにくいコードを書けるようにという志で作られた MISRA C ですが、
関数の末尾以外の return を禁止するという誰得ルールを筆頭に使い物にならない制約が多すぎます。
役に立つところといえば、これをそのまま採用するところの技術力は信用できないという判断材料になることぐらい。
Re:MISRA C という失敗 (スコア:1, すばらしい洞察)
> 関数の末尾以外の return を禁止する
なぜ禁止なのかわからない人にコードは書かせたくないなあ
Re:MISRA C という失敗 (スコア:1)
>> 関数の末尾以外の return を禁止する
>
>なぜ禁止なのかわからない人にコードは書かせたくないなあ
この人深いネストが連なった山脈みたいなコードを書いてそう。
そんなコードはフルHDモニタが普及した今でも読みたかないよ。
Re:MISRA C という失敗 (スコア:1)
なぜ禁止なのか書いていないから「そのコーディング規約」はダメなんです。
ルールが独り歩きする原因です。
わかりましたか?
Re: (スコア:0)
そだよね。ちゃんと考えられてるコーディング規約って理由も明記してある。
理由が分からんと本質が分からず、応用が効かない。
理由が書かれてないならコーディング規約が完璧に漏れ無く書かれてないと、
ちょっとしたイレギュラーなところではどうしていいか判断が効かず、結局各々の記述をしてしまいますから。
Re:MISRA C という失敗 (スコア:1)
禁止の理由はよくわからないんだけど、
関数途中で抜けたいときには Exception を上げればいいということですよね。
そんで呼び出し元で処理する。
Re: (スコア:0)
CにExceptionなんてないような…
Re: (スコア:0)
なんだろう?可読性がよくなる訳じゃないし。
末尾最適化されやすくなる(かもしれない)くらいしか思い浮かばないなあ。
Re:MISRA C という失敗 (スコア:2)
私じゅうあ可読性は上がると思います.
それこそ「山脈のようなコード」でなくても.
returnの場合は様々な要因が絡むからアレだけど,
似た例ではif文とif句の違いがあります.
if(a){
x = A;
}else{
x = B;
}
とあるものは,
x = if(a) A else B
あるいは,
x = a?A:B;
の方が大抵の場合は見通しが良いですよね.
文頭から, 「あ, xになんか代入すんだな」っていうことがわかります.
同じことがreturnの場合にも言えるんじゃない?
関数の最後から見て, 何を返すのかを先に知ることで,
見通しは良くなるんじゃないでしょうか?
ここまでの説明で, returnまでの長さが問題じゃないことはわかると思います.
Re:MISRA C という失敗 (スコア:2)
ごめんなさい, 変なタイポが入りました
# ○私 は : ha
# ×私 じゅうあ: jha
Re:MISRA C という失敗 (スコア:1)
関数の入り口と出口がそれぞれ一箇所に限定できるので、処理手順の流れを正順・逆順追っかけるのが楽になるということでしょうか。しかし、いまなら統合環境では return goto break continue といった処理手順に影響するキーワードは強調表示できるので、 それほど問題にならないような気がします。
Re:MISRA C という失敗 (スコア:1)
そう、こういうのはだいたい昔の親切でない言語や開発環境を想定した規約なんだよね。
実際10年ぐらい前には、巨大メソッドの途中にreturn文があって以降が実は使われないゴミ、とかいう酷いプログラムを見かけたこともある。
なので、そういう時代は出口を一か所にしなさいという主張にも、その結果として巨大なif文やらが作られてしまうことが多々あるものの、それでも一定の価値があった。
でも今はJavaなんかだとそもそもそういうのは言語自体でエラーとして検知してくれるし、何より一つ一つのメソッドを小さく作るべき、って思想も浸透してきてる(と思う)ので、この規約は可読性を下げるだけの厄介者でしかない。
Re: (スコア:0)
デバッグか何かで、ツールで関数末尾に処理を自動挿入するとかは?
人間は一度に少しの事しか覚えてられないので、この場合はこれで終わりということが
明確に分かる、途中returnには意味があると思うけどなあ。
これを禁止する人は、例外がある言語でも例外は使えないんだろうか?
Re: (スコア:0)
むしろ例外のない環境に過剰適応した結果「途中returnなんて解放漏れが発生する! 論外だ!」とか吹き上がっちゃってるんじゃね?
Re: (スコア:0)
なるほど解放漏れかー。その発想はもう忘却の彼方だったなあ。
これはどうも、goto禁止令と同種の制約っぽいな。
goto同様、途中returnも解読困難に記述することは可能だから、
そういう手合いには使用を禁止した方が読めるソースになるって事かな。
Re: (スコア:0)
その程度の事でも可読性が下がるような冗長なコードをメンテしているのでしょう
一度製品に載ったコードはなかなか変えられないなんて良くある事です
作り直したくなる気持ちを抑えて障害解決しようと頑張る方々には頭が下がります
Re: (スコア:0)
> なぜ禁止なのかわからない人にコードは書かせたくないなあ
なぜ禁止なのかわからない私は一緒に仕事をする機会はなさそうです。
私はそんなコードを書かずに済むし、お互いによかったですね。
Re: (スコア:0)
なぜ禁止すべきでないのかわからない人にコードを書かされたくないなあ。
# 論理的な理由があるならそれを書けば済むだけなのに決まってこんな罵倒しか返ってこないんだよな
Re:MISRA C という失敗 (スコア:1)
途中で return すると、リソース解放し忘れるミスが増えるから。
コードの見通しの悪さによる保守性悪化と、リソースリークの潜在的危険性を天秤にかけた。
理由としてはそれだけ。
MISRA C の主目的は深刻なバグの入りやすいパターンを避けることだから
大多数にはバカバカしいルールでも、たった一人の間抜けに躓かないための妥協が多くなる。
C にデストラクタがあればこんなルールは生まれないね。
Re:MISRA C という失敗 (スコア:1)
それならそこだけ禁止すればいいだけなのに、なんで全部禁止にしたがるのでしょうね?
その関数がリソース解放しているかどうかぐらい書いている人もレビューする人も分かりますよね。
Re:MISRA C という失敗 (スコア:1)
その関数が一人の人間が見通しの良い行数以内で一度書いて完成、以降の改造も未来永劫ないとは限りませんから。
Re:MISRA C という失敗 (スコア:1)
「そこだけ禁止」言うは易し、行うは難し。
文脈に依存したコーディング規約の適用はすぐに破たんする。
たとえば、リソースを使っていなかったモジュールを後から使うように変えたら、途中 return は全部書き換えるのか。
そもそも管理リソースを減らしたくて一律に適用しているのだから、本末転倒。
Re:MISRA C という失敗 (スコア:1)
当たり前ですが、何か問題でも?
全然破綻している例えになってませんよ。
>そもそも管理リソースを減らしたくて一律に適用しているのだから、本末転倒。
管理リソース削減のためにコードを難解にするほうが本末転倒だと思うのですが、
どうやらMISRA C使っている業界とは住む世界が違うようです。
Re: (スコア:0)
MISRA C使っている業界は工数に占めるコーデングとテストの割合が10%未満だしなあ。
大体数年かけて、仕様策定に50%弱、出荷前までのレビューに同じく50%弱使って、設計とコーディングとテストは残り工数でやる感じ。
常に10件以上の開発が並行して走っていて兼務するため、いちいち覚えておけないので毎回その場で把握と問題解決をする。
Re:MISRA C という失敗 (スコア:1)
残念ながらMISRA C++というC++に対応したとされるものがありまして、
それにも変わらずばかばかしいルールが残ってるんですよね
Re: (スコア:0)
たった一人の間抜けはどんな規約を用いても深刻なバグを作りこむのであまり意味がないのでは。
むしろ、保守性が悪化することでリソースリークが起こりやすくなる場合もありますし(実際そういうソースに出会ったこともあります)。
Re: (スコア:0)
> 大多数にはバカバカしいルールでも、たった一人の間抜けに躓かないための妥協が多くなる。
間抜けに躓かないのを基準にルールをつくると、本来不要なルールがいくらでも増えていく。
コードの健全性を期待するなら lint みたいなチェッカで評価するのを標準化するほうがより適切かと。
> C にデストラクタがあればこんなルールは生まれないね。
C でデストラクタ相当の処理を設けたいなら、リソース割当と解放をする呼び出し関数を経由するんじゃないかな。
Re:MISRA C という失敗 (スコア:1)
コードの健全性を期待するなら lint みたいなチェッカで評価するのを標準化するほうがより適切かと。
そんなツールが手軽に使えれば、泥臭いデザインパターンみたいなコーディング規約に頼らなくてもいいのだが。
無いものねだりは仕方がない。
オフトピ (スコア:0)
#ですな。切って捨ててハイ終わりってな議論の仕方は建設的ではないし、結論まで遠回りになってるだけ。
#スラドではもちっと大人な会話であって欲しい。
Re: (スコア:0)
Re: (スコア:0)
おもおかモデが付いてますけど同感です。
遵守はやりすぎとしても、理由すらわからない人のコードはなるべく読みたくないです。
今でこそCソースのバグ探しに借り出されることもなくなりましたが、
みたいなプログラム(とくに他人の)は追跡の苦労が尋常じゃありませんし、
中途returnのパスの一箇所だけがcloseを忘れていて、それが積もり積もると…
みたいなバグに脱力した幾多の経験がフラッシュバックして陰鬱な気持ちになります。
コードの健康のため、return≒gotoくらいに考えておくのが吉だと思いますよ。
Re: (スコア:0)
なるほど、なぜ同意する人が多いのか謎でしたが見て回ってわかりました。
10年前の考え方がまだ残ってるんですね。
Re:MISRA C という失敗 (スコア:1)
C言語の規約なんだからそれでいいんじゃない?
C++で強制されたらなんで?になるけど。
で、C++で書いた後「C言語じゃないんで関係ないですよね」が通用するのかどうか調べてみたけどMISRA C++ってのもあるんだな。
http://www.klocwork.com/products/documentation/current-ja/Klocwork_%E3... [klocwork.com]
6-6-5でC言語と変わらず途中returnダメって書いてあってこれ制定した人たちにはがっかり。
例外は禁止してないところからも実際に何を理由に禁止にしたいのかさっぱりわかりません。
Re: (スコア:0)
EC++には例外がないから。
という説。
Re: (スコア:0)
15-x−xで例外についてチェック項目があるんでそれは理由にならないですね。
Re: (スコア:0)
絶対に禁止だと以下のような場合に制御変数が必要になるので
余計に分かりにくいコードになっちゃうよね。
適切に分割されていれば不要かと。
function search() {
for (...) {
for (...) {
if (found) return x;
}
}
return null;
}
Re:MISRA C という失敗 (スコア:2, おもしろおかしい)
元コメがACなら、みんなACで返すしかないじゃない!あなたも、わたしも!
Re: (スコア:0)
コメント1つを除いてこのツリー全部ACでんがな。
Re: (スコア:0)
はいはい
Re: (スコア:0)
そもそも「コレ」自体がACだし論になってないから同レベルで相手してやってるだけ。