「例解UNIXプログラミング教室」訂正や補足
いただいたコメントなどをもとにした訂正や補足です。コメント下さった皆様、ありがとうございます。
4章 標準入出力ライブラリ
4.1.1節 1文字ずつの読み書き(113ページ)
次のように書きましたが、
ただし getc や putc がマクロとして実現されている場合にはそれらへのポインタ(関数へのポインタ)をとることができません.なお,実行環境によっては getc などが関数として実現されていることもあります.ですから,これらがマクロであるか関数であるかに依存しないコードを書くべきです.例えば副作用を起こす式(例えば i++ など)を putc などの引数に与えてはいけません.
新しいC言語の規格(JIS X 3010:2003)では、ライブラリ関数(getc や putc)がマクロで実装されている場合でも、同名の関数がライブラリに定義されていることを要求しています(7.1.4節)。その場合、次のようなコード
1: char c; 2: int (*p)(); 3: 4: c = getc(); 5: p = getc;
においては、4行目ではマクロ getc が使われ、5行目ではライブラリにある関数 getc が使われることになります(5行目の getc の後に開き括弧がないのでマクロ展開が起きない)。
同じ規格においてはさらに、マクロとしてライブラリ関数が実装される場合には、その引数はただ一度だけ評価される、ということを規定しています(7.1.4節)が、getc(7.19.7.5節)と putc(7.19.7.8節)については、stream 引数については2回以上評価されることがあるとなっています。
いずれにせよ、C言語にはさまざまな実装があることから、副作用のある式を引数に与えないようにプログラムした方が安全でしょう。
6章 ファイルシステム
ノート6.3(195ページ)
「ディレクトリの読み許可は、そのディレクトリが持っているデータ(ただしファイル名だけ。iノード番号はだめ)を読む許可で」とありますが、これは誤りで、iノード番号も読めます。つまりディレクトリの読み許可は、p202から説明するディレクトリストリームを開く許可だと考えるとよいでしょう。
解答6.10 file1.c について
if の入れ子が深くなるのを嫌って goto を使っていますが、やや乱用の感があります。 相互再帰を使って書き直してみました → files1a.c (文字コードはEUC。本文中のコードの tgz ファイルにも収録してあります)
10章 端末(1):端末、端末ラインディシプリン、termios 構造体
ちょっと休憩10.1(335ページ)
ASCIIコード表でコード番号32に対応する部分が「~」となっていますが、これは正しくは空白文字です。
11章 端末(2):エスケープシーケンス、curses ライブラリ、擬似端末
解答例11.6(361ページ)および解答例11.7(363ページ)
以下のコード
/* 表示物の定義 */ enum { WALL = '#', ROCK = ''', PIT = '^', SELF = '@', SPACE = ' ', };
の部分において「ROCK = '''」は誤りで、正しくは「ROCK = '\''」です。
最終更新日時:2013年12月8日