金言
思い出してしまった.
- http://lists.sourceforge.jp/mailman/archives/gauche-devel-jp/2004-August/001077.html
- http://lists.sourceforge.jp/mailman/archives/gauche-devel-jp/2004-August/001084.html
あ゛ぁこのへんのメッセージを読ませたい人が身近にいる... (それにしてもshiroさんはどこまでも丁寧だ.すばらしい)
Cで長さNの配列以外をエラーにする
その人が参考にした,と挙げたページ.
引数リストに int (*a)[10]
と書くなんて初めて見た.こうして,「配列先頭を指すポインタのアドレス」を渡すと長さ10以外の配列は弾かれるらしい... ただし静的に取ったもののみ(ぉぃ).参照するときには (*a)[3]
とかする,というのは落ち着いて考えれば分かる.... しかし,だ.
例えば構造体 student
の配列を渡すとメンバ age
を1ずつ増加させる関数 incAge
を考えよう.上のように,例えば「 student myStudents[10]
」に特化させて書くと,型は void incAge(student (*a)[10])
である.んで,中では(カウンタi
を使って) (*a)[i].age += 1;
とするのが正解.しかしその人が「コンパイル通ったんで実行したら "stack corrupted" とか言われるんです〜」と見せて来たコードは a[i]->age += 1;
のようなものだった.何しろこのような奇妙な渡し方に慣れていなかったせいで,なぜこれがおかしいのかすぐには分からなかった.型やポインタはがしの初歩的なミスはコンパイラが検出してくれるだろうから,どうして不正なアクセス*1が行われるのだ?
↑が型チェックを抜ける理由: a[i]
の型は student[10]
で,実質的には student *
だから ->
できるのね... orz
ともあれ,結局最後には普通に void incAge(student a[], int nStudents)
とさせた*2.