Togetterで先日まとめた「#俺が見たクソコード選手権 まとめ」についての話です。
そこそこ反響があったのですが、「書いてある中身がよくわからない」という反応もいくらかあったので、一部抜粋してちょっとだけ補足してみたいと思います。
なるべく書いた側の身になって考えてみたいと思います。
何かコメントで見当はずれなところがありましたらご指摘よろしくお願いします。私もいわゆるクソコードを書いてしまうことがよくあるので。
個人的にはこれが一番衝撃的だった。 きっと何かトラウマがあったんだと思う。 x = y; x = y; // 不安だからもう一回 #俺が見たクソコード選手権
— Norihisa Miyakawa (@m_nori) April 3, 2012
掃除機で同じ所を何度もかけるようなノリですね。過去に何があったんでしょうか。
一応、マルチスレッドの処理などを適当に書いてしまうと、代入した変数の値が適当なタイミングで勝手に書き変わってしまうことがあります。
もっとも、その場合でも変数にvolatile宣言をしておかないと最適化で取り除かれてしまいますが。
if (1 == 2) {…} これだわ・・・哲学やねんなもう・・・ #俺が見たクソコード選手権
— エンター (@enter4129) August 6, 2013
if(false){ printf("エラーです"); } そうですねエラーですね #俺が見たクソコード選手権
— EOF (@eofor0) August 6, 2013
絶対に実行されないコード。適当な変数が定数になったとき、機械的に置換していくとこういう記述が出てくるおそれがあります。
普通のコンパイラならWarning出してくれるような?
int n; switch (x) { case 0: n = 0; break; case 1: n = 1; break; case 2: n = 2; break; …ずっと続く… } #俺が見たクソコード選手権
— Fujio Kojima (@Fujiwo) August 6, 2013
なぜか変数の値でわけて即値で代入しようとしています。nにxの値を代入すれば終わりなのですが。
xが場合分け用の変数か何かだったんでしょうか。2,3種類の分岐ならまだわかりますが、「ずっと続く…」というところに執念を感じますね。
#define ZERO 0 // 0 #define ONE 1 // 1 #define TWO 2 // 2 これが100まで続いてた #俺が見たクソコード選手権
— らーし(航空ハスキー犬) (@ra_si) August 6, 2013
おそらく「ソースコード中のマジックナンバーはよくない」という言葉を字面通りに解釈してしまった結果です。
マクロでdefineすると単にコンパイルの前段階で数字に直されてしまうので、コンパイラから見た状態は数字が書いてあるのとまったく同じことになります。
そもそも、マジックナンバーがよくないといわれる理由は可読性であったり保守性であったりといった人間に対しての話で、コンパイラに対してではありません。
/*このコメントを入れると何故か動く*/ #俺が見たクソコード選手権
— 速水 瞬次@D-STAGE (@hayamism) August 6, 2013
謎です。いろいろ考えてみましたが、コメントの有無で結果が変わることって原理的にありえるのでしょうか。
コメントアウトの意味かな?
int flag = 4; // フラグに2を代入 #俺が見たクソコード選手権
— イトウ アスカ (@itoasuka) August 6, 2013
きっと昔は2だったのでしょう。
コメントが保守性を下げてしまった結果。
<?php $HelloWorld = "Hello World"; print "Hello World"; ?> #俺が見たクソコード選手権
— おかゆ@がんばらなかった (@okayu_k) August 6, 2013
Hello Worldの変数を使った…使っていない版。
変数名というのはあまり具体的な名前にしすぎると今回のように変数としての雰囲気がなくなってしまいますが、ひどく抽象的にしてしまうと何の変数かわからなくなりますし、ちょっと悩むことがあります。
意図した処理はされませんが、意図した動作はします。
if(num==10){ point && mode = 2; } #俺が見たクソコード選手権 これは出来るんじゃないのかとがんばったあの日
— あい。の人@TGS学生ブース参加 (@AI_nohito) August 6, 2013
point = mode = 2; と書くときっと思っていたよう動きます。気持ちが伝わってくるので好きです。
#include<studio.h> #俺が見たクソコード選手権
— 『迷走』の頂 ゆしゃん (@Yushan_knct) August 6, 2013
stdioをstudioと書いてしまう例。私もはじめはなんでuないんだろう?って思っていました。
stdioは “standard input/output” の略です。「えすてぃーでぃーあいおー」って読むしか道はないのでしょうか。
/* 気持ち遅らせる */ int i; for (i = 0; i < 10000; i++) ; #俺が見たクソコード選手権
— tak (@erre_factory) August 3, 2013
組み込みだと「気持ち遅らせる」ためにこう書いてしまうことがあります。
どっちかというと、なぜここで遅らせなければならなかったのかというのが気になります。
マルチスレッドの同期などが目的だとするとなかなか恐ろしいです。
b=a/rand(); #俺が見たクソコード選手権 天文学的確率なので大丈夫です(キリッ
— やまねこ@楢ノ木技研 (@felis_silv) August 6, 2013
randで0が生成された瞬間にエラーを出しますが、そのようなことは「あまり」起きません。おおこわい。
値の分布も一様でないですし、なかなか不思議な文だと思います。
void foo(int i){i=0; //以下略} #俺が見たクソコード選手権
— まりも@はぐ充 (@Marimoiro) August 6, 2013
受け取った引数の値を即廃棄。
これだけ見ると変ですが、インターフェースを変えずに実装だけ変えるとこういう事態は起きえます。
$a++; $a–; //文字列型を整数型に変換する #俺が見たクソコード選手権
— ゆう@創作合同参加者募集中 (@_lhy) August 6, 2013
動的型付けな言語で苦心して数値型にした例。
言語名とコメントに書いた文章そのままで検索エンジンにかければきっと欲しい結果が得られたと思います。
まとめ
よくある間違いから、その人なりに苦心して生み出したオリジナル謎コードまでいろいろとありました。
私にとっては、人間の直感とプログラミング言語の雰囲気はずれているのだなと思うところがありました。機械への命令を記述する一連の決まり事のことを指してプログラミング「言語」と呼びますが、それはどうしても人間が人間へ伝えるものとは大きく異なってしまうようです。
最後に、私の好きなツイートを引用しておきたいと思います。
純粋にソフトウェア系の人って病んでいくよね.やっぱり何か人間の直観に反するところがあるんだろう.
— あの人 (@_anohito) April 21, 2013
プログラミングが、入門者にとっていろいろとやさしい環境になるといいですね。