わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

最初の壁,デバッグ完全解説

今日紹介する2冊の本は,Cプログラミングの授業を聞き,見よう見まねでプログラムを書いたりしてきたものの,期待通りに動いてくれない,という人にとっておすすめの読み物です.

プログラムの 最初の壁

プログラムの 最初の壁

2ページ見開きで一つの話題として,88個の「話」があり,色即是空(25話)とかおでん(63話)とか,毎回,プログラミングと直接関係ないものを枕にしていて,楽しく読むことができました.
サンプルコードの例でも,見て明らかな間違いというのは見当たりませんでした.そのまま動かせるコードは薄黄色,動かすためではないコード断片は灰色の網掛けで区別されているのも,好感が持てます.
p.211以降のAppendixも,分かりやすくまとめられています.そういえば本文中では処理系依存のことが語られていませんでしたが,Appendixを読むと,ANSI (C89)を対象とし,WindowsUnixへの言及もあります.
サンプルコードにケチをつけるなら,86話(pp.202-203)でしょうか.que, ans1, ans2, ans3という4つの文字列ポインタを定義し,que[x]の選択肢はans1[x], ans2[x], ans3[x]としていますが,問題文ごと,選択肢ごとに配列にするのはまずい設計で,問題文が増えると,問題文と選択肢の対応関係が分かりにくくなります*1
問題文と選択肢に関する構造体を定義し,複数あるのならその配列にするほうが自然でしょう.構造体配列変数を一つ宣言して,{ }の入れ子を使えば,一つの宣言文でデータが格納できます.

C言語 デバッグ完全解説 (Gihyo Technology)

C言語 デバッグ完全解説 (Gihyo Technology)

軽い気持ちで読むと,痛い目にあう本です.学生で読みたいという人は,正対して読まないといけないと思ってください.各ページ,情報・知識・知恵がぎっしり詰まっています.
いろいろなバグとその対処法を紹介しているのはもちろんですが,バグを出さないための心がけや,Cプログラミングの「心構え」が随所に書かれています.心構えについては,「6.3.2 C言語は移植性がない」に集約されています.
読み方としては,まず6章から読んでもいいと思います.まあ著者の意図は,1章pp.11-12にある5つの「バグありコード」をじっくり見てバグを見つけてもらい,1個か2個は見つけられないだろうから,2章から順に読んでいってね,といったところではないかと想像します.
さて6.3.2節の全体は素晴らしいのですが,途中にびっくりした記述がありました.

このように考えると,C言語ではたとえば
(略)

  • 構造体どうしの==による比較の際に,パディングにゴミが入っていると,異なるものと判断されてしまう.

(略)
といったような,ある意味「手抜き」「乱暴」とも言える言語仕様も,実に納得のいくものであることがわかります.
(p.301)

構造体どうしは,==演算子で比較できないはずです.手元の書籍やJIS規格にも当たり,検証コードを書きましたが,GCCで-std=c99でも-std=gnu99でも,エラーになりました.
構造体に対する==演算子の利用例は,p.164にもあります.memcmpを使うのなら,エラーにはなりませんが,それでもなお,パディングの問題があるので,やってはいけない処理ですね.http://www.st.rim.or.jp/~phinloda/cqa/cqa11.html#Q5 の説明が分かりやすいですし,本でも,直後のページに,構造体のメンバどうしを比較することで,等価性を判定する関数の例があります.

*1:まあ,問題文が多くなれば,ハードコーディングではなく,ファイルやデータベースから読み出すことになるのですが.