宗教論争にさえならないマヌケなコーディング規約

高木です。おはようございます。
今日の話題は「コーディング規約」についてです。
先日、自分のTwitterに投稿した内容の焼き直しになります。
私自身、あまり細かいことにこだわるのは好きではないので、箸の上げ下げまで規定するようなコーディング規約には反対です。
自分がコーディング規約を作る立場であっても、そんなうるさい規約は作りません。
ところが、世の中にはうるさい規約がいろいろあるようですね。
インデント幅をどうするとか、括弧の位置がどうとか、ifの後にスペースを入れるとか入れないとか・・・・・・。
このようなルールは、好みの問題もあって、いわゆる宗教論争に発展しがちだとよくいわれます。
そんなどうでもいいことに労力を払うぐらいなら、もっと別にやるべきことがあるだろうと思います。
どうでもいいようなコーディング規約も問題なのですが、それよりもっとトンデモな規約が世の中にはあるものです。
その多くは正気を疑うような内容です。
具体例を挙げていきましょう。
暗黙の型変換は行わず、明示的に型を変換すること
プログラミング言語はCを想定しているのだと思います。
こんなコーディング規約を見て疑問に思わないプログラマーは、ちょっと問題があります。
暗黙の型変換にはどんなものがあるのか考えれば、その狂気が見えてきます。
整数拡張、通常の算術型変換、既定の実引数拡張、算術型どうしの変換、関数型から関数へのポインタ型への変換、配列型から配列要素へのポインタ型への変換、ポインタどうしの変換、ポインタと整数型の変換といったところです。
このうち、確かに明示的にキャストすべきものもあります。
異なる種類のポインタ間の変換とか、ポインタと整数型の変換なんかはその典型でしょう。
一方で、これは暗黙の型変換にまかせるべきだろうというものもあります。
たとえば、関数型から関数へのポインタ型への変換とか、配列型から配列要素へのポインタ型への変換とかがそうです。
もし、それらを明示的にキャストするのであれば、次のような複雑なコードを書かなければならなくなります。
1 2 3 4 5 6 | #include <stdio.h> int main(void) { ((int(*)(const char*))puts)((const char*)"hello, world!"); } |
これはもう、プログラマーに対する嫌がらせ以外の何物でもありませんね。
こんなコードをすらすら書けるプログラマーはそんなにいないと思いますよ。
また、整数拡張や通常の算術型変換に依存することも禁止されているわけですから、明示的にキャストが必要になります。
たとえば、uint16_t型の変数aがあるとしましょう。
変数aが何らかの演算のオペランドになるとき、暗黙的な型変換が発生します。
整数拡張の場合、処理系によってどんな型に変換されるかが変わってきます。
具体的には、int型が16ビットの場合、変数aはunsigned int型に変換されます。
int型が32ビットであれば、変数aはint型に変換されます。
つまり、処理系を特定しなければ、暗黙の型変換に変わる明示的にキャストを行うことができないのです。
そのような処理系に依存する動作を否定する意味でキャストを行うという考え方もありますが、それなら常にuintmax_tにキャストしなければなりません。
これではいたずらにパフォーマンスを低下させることになってしまいます。
このような正気の沙汰とは思えないようなコーディング規約が、残念なことに世の中には蔓延しています。
私もときどき他社のコーディング規約を目にすることがありますが、多くの場合、ツッコミどころ満載ですね。
たまには馬詰に負けないように1,500字超えの投稿をしてみました。