
いよいよと、初夏の装いがギラギラと目に痛い季節がやってまいりました。なんやかんやと、季節や地球に悪態をついておりますが、湿気と暑さには本当にめっぽう弱いTeamDyquemで御座います。皆様、こんにちは。
まだ6月だというのにも関わらず、既にやや茹だる様な様相を呈しております関東平野。湿気にやる気を削がれて、死んだ魚の方がまだ生き生きとした目をしているTeamDyquemですホントに。
反面、冬は大好きなのでありますよ。冬最高。凍れ、全てよ。
さてさて。 今回は、バグと上手に付き合う方法につきましてヒトネタ。 プログラマ視点からはこんな気持ちで臨むと良いよ、という話でありますが、プログラマでは無い方も是非サラっと一読頂けましたら幸いです。

プログラミングというものは、良くも悪くも結局はヒューマンエラーとの闘いであるとも言えるでしょう。バグは人為的ミスである以上、高尚な合理性を掲げ、如何に芸術性を追求してみたところで、バグのあるモジュールの存在意義には常に疑問符がついて回ります。 では、「バグが無いプログラム」とは何でしょう。それは勿論、読んで字の如しではあるのでしょうが、突き詰めてみればバグというものは結局、設計者の意図に反した動作を行う設計になってしまっているプログラムの総称であり、バグが無い事を理論的に証明するためには、その課程において設計者の脳内を通過しなければならず、これはつまり所謂「悪魔の証明」よろしく「無い事を証明できない」典型的な詭弁と相成るわけであります。 バグが無いプログラムを定義する事の無意味さについてはこの通りなのですが、ここで重要な点は、「バグが在る」としても、それを機械的に発見させる為の「種」を植えておく事でありましょう。それはあたかも白血球であるかの様に、自身の仕組み内にて潜在的不穏因子、つまり人の力ではなかなかに見付け出す事の難しいバグ等をも自動的に検出し、排出出来る様なシステムとして稼働します。設計段階において人が全てのヒューマンエラーを排除する事は殆ど不可能でありますから、その補助システムを予め組み込んでおく形が望ましく、また合理的でありましょう。
さて、ものっすごく冗長に書いてみました。
バグを発見するスキルと、可能な限りバグを作らないスキルは別物であるのですが、今回は後者に言及する為に必要な冗長さとしてご容赦下さい。最も大切なこのフェイズを十分に実装しておくと、後々に不可解なバグで何日も時間を浪費する可能性も下がり、結果として、貴重な制作時間の短縮に大きく貢献する事になるのです。
さて、 「脱、バグ苦悩」プロジェクトの第一弾としまして、今回は「Assert:(アサート)」を取り上げてみましょう。
 「脱、バグ苦悩」プロジェクト第一弾 ~ Assert ~
assertとはデバッグ系ユーティリティの一つで、プログラム設計者の定める仮定が満たされていない場合にその時点で実行を停止させ、利用者、又は設計者へ、意図しない動作が発生した瞬間を通知し被害を最小限に食い止め、もしくはバグ修正への情報を提供する為のツールです。
簡単な例を挙げてみましょう。
namespace { const unsigned int num = 3; const char* nameTable[ num ] = { "Dyquem", "Marimo", "Nekoris", }; }
const char* getName( unsigned int aIndex ) { assert( aIndex < num ); return nameTable[ aIndex ]; }
関数 getName へ 3以上の引数を与えた場合、assertがそれを捕捉しプログラムは停止します。もしもassertが無ければ、いったいどんな事が起きるでしょう。 このケースならば、謎のメモリ領域にたまたま存在しているグチャグチャなNULL終端文字列を返し、受け取った処理はそれを正規の「名前」であるとして処理は進み、仮にそれが住所録アプリであるならば、最終的なユーザーレベルの視点には「グチャグチャな名前の人が、アドレス帳に時々現れる」等といった、原因究明のなんとも厄介そうなバグへと成長するでしょう。
assertはC言語標準関数としてassert.h により定義され、そのまま使用する事も出来ますが、TeamDyquem的には以下の様に拡張した上で使用しています。
void Abort( const char* apFileName, unsigned int aLine, const char* apFormat, ... ) { vsnprintf_s等で、引数の文字列を表示する、等 exit( 1 ); }
#define Assert( aExpression, ... ) {\ if( bool( aExpression ) == false ){\ Abort( __WFILE__, __LINE__, __VA_ARGS__ );\ }
// ex. Assert( aIndex < num, "[getName] Illegal argument (%d/%d)", aIndex, num );
VisualStudioでのサンプルです。__VA_ARGS__等はコンパイラが定める定数ですので、お使いのプラットフォームに適時合わせて下さい。
この様に拡張すると、実際には
[test.cpp](240行目): [getName] Illegal argument (3/10)」
この様なメッセージを表示した後にプログラムが停止します。 設計者が設計時にこのメッセージを目にすれば、直ちに原因となった箇所をチェック出来ますし、ユーザーさんがバグ報告をしてくれた際にも、このメッセージを教えて貰えるのとそうでないのとでは、解決までに要する時間も大きく異なるでしょう。
Assertは、それはもう山の様にありとあらゆる箇所へ仕込んで置く事が良いでしょう。 個人的には、基本的にポインタの類は全て触る前にはAssertでチェック、配列アクセス言わずもがな。switch文にて意図しないcase値は全てAssert。また、本稿の話からは少しだけ逸脱しますが、Static Assertという機構も併用しています。
 リリース版では
あんまり仕込みすぎると、実行速度に影響があるのではないかと思われるかもしれませんが、その様な事はありません。 条件コンパイルにて、くだんのAssertマクロ内容を空にする様にするだけで、実際にリリースするバージョンでは全てのAssert文が自動的に消滅してくれますね。

100利あって1害無し。 心ゆくまでAssertを仕込んでいきましょう。
さーて、次回のサザエさんはっ
これがAssert例外処理をミスりまくっている代表例だ! プログラマちょっとここへ来て正座しろ!的なお話として、
「スカウターの爆発」
「名前を間違えた場合の、デスノートの挙動と動作」
「バルス」
を、お送りします。(するのか?)
- 関連記事
-

シリーズ記事まとめ
■Aニュース、ガジェット通信 寄稿記事
「『連載.jp』寄稿「ゲームプログラマが語る「プロ棋士に勝ったAIは、タクシー基本無料化をもたらす?」」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る ”買わない理由”がもたらす充足感と、開発者達の心理」」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る アップデート版に潜む開発者モラルハザード」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る ソフトやアプリと携帯ゲーム課金における経済行動学」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る。新しいゲーム機が定期的に生まれる理由」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る 楽しさの仕組み ゲームメカニクス」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る 3Dテレビとゲームの微妙な関係 その打開策」」
「『Aニュース/ガジェット通信』寄稿「ゲームプログラマが語る 無料アプリのビジネスモデルと舞台裏」」
「『Aニュース/ガジェット通信』寄稿「新発表ラッシュに見るクラウド大航海時代の幕開け」」
■ゲーム制作初心者さん向け系
ゲームプログラマが語る。なんちゃってリードプログラマにはなるな!ゲーム造りで放棄してはいけない大切な事
ゲームプログラマが語る。今さら聞けないフレームレートに纏わる話。秒間60?16ミリ?
ゲームプログラマが語る。「浮動小数点」と商業レベルで上手に付き合う方法
「ゲームプログラマが語る。ゲーム制作初心者の方へ小ネタ「クォータービュー入門」」
「ゲームプログラマが語る。「正しい乱数」が彩る確率世界とエンターテイメント」
「iPhoneアプリ、ゲーム制作初心者の方へ小ネタ「線分と円の交差」」
「iPhoneアプリ作者より、ゲーム制作初心者の方へ小ネタ「2Dベクトル」」
「iPhoneアプリ作者より、ゲーム制作初心者の方へ小ネタを一つ」
■「プロのゲームプログラマとして、ゲーム製作に関する書評を」シリーズ
ゲームプログラマが語る書評:「MMORPGゲームサーバープログラミング」を読んでみた
ゲームプログラマが語る書評:「ゲームプログラマになる前に覚えておきたい技術」を読んでみた
ゲームプログラマが語る書評:「ゲームエンジン・アーキテクチャ」を読んでみた
■個人でも出来る、マルチプラットフォーム開発関連
「ゲームプログラマが語る。iOSゲームをWinマルチプラットフォーム開発・その4」
「ゲームプログラマが語る。iOSゲームをWinマルチプラットフォーム開発・その3」
「iPhoneアプリ作者が語る。マルチプラットフォーム化その2・アトミック型定義のススメ」
「ゲームプログラマが語る。iOSゲームをWinマルチプラットフォーム開発・その1」
■リリースしました系
「PASTEL-ORBIT/TeamDyquemアプリ第19弾。ローグライク決定版「隣人は魔王」をリリースしました。」
「TeamDyquemアプリ第18段。ご当地バトルRTS「埼玉クエスト」をリリースしました。近隣の県を滅ぼそう(*-_-*) 埼玉以外でも遊べます #47app」
「アプリ新作「ネコりす マカロン」をリリースしました」
「埼玉県ご当地アプリ、「タッチ the さいたま」をリリースしました #47app」
「アプリ新作「ひよこガーデン」をリリースしました」
「TeamDyquem新作。結構真面目なアクションパズル「ネコりす」リリース」
「iPhoneアプリ作者が、iアプリ「泡リス女子部 for iアプリ」をリリースしました」
「自作iPhoneアプリ改良版、「ネコがゴミのようだネ:アーケード」をリリースしました」
「iPhoneアプリ作者が、「まりも育成」for iモードをリリースしました」
「iPhoneアプリ新作 「ナタ・デ・ネコ」 をリリースしました」
「秋刀魚は関係ないけれど、新作「i-Wishbone」リリース」
「アプリ新作「ネコがゴミのようだ」。プロモ動画をアップしてみた」
「「泡リス 女子部」、販売開始」
「AppBankにまりも紹介記事が!」
「ゲームプログラマとして参加。ご当地47都道府県アプリプロジェクト #47app」
□ビジネス系
「ゲームプログラマが語るドコモiPhoneと、インフラから合法的に大金を抜くスキーム」
「ゲームプログラマが語る。秀丸エディタのビジネスモデル」
■SFネタ系
「ゲームプログラマがSFを語る。意識はどこからやってきて、死んで、そして何処へ行く?」
「ゲームプログラマが語る。気の遠くなるスキもない程の、宇宙の話」
「iPhoneアプリ作者が語る。流れ星に馳せる真実」
「iPhoneアプリ作者が警笛。どこでもドアの使い過ぎには注意」
「iPhoneアプリ作者が語るSETI理論。異星人さんは何処!?」
Theme:プログラミング
Genre:コンピュータ
|