| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
このノードでは,頑丈なソフトウェアを書くための約束について 説明します.また,エラーメッセージの書き方, コマンド行インターフェース,ライブラリの動作についても標準的な方法を 解説します.
4.1 頑丈なプログラムを書くには 4.2 ライブラリ関数 4.3 エラーメッセージの形式 4.4 一般的なインターフェースの規約 4.5 グラフィカルインターフェースの標準 4.6 コマンド行インターフェースの規約 4.7 長いオプションの表 4.8 メモリの使い方 4.9 ファイルの使い方
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ファイル名, 行, ファイル, シンボル等のどんなデータ構造にも, 長さや個数について勝手な制限は設けてはいけません. データ構造用のメモリは動的に確保しましょう. Unix ユーティリティは「長い行はだまって切る」 ものがほとんどですが, GNU のユーティリティではこれは容認できません.
ファイルを読むユーティリティは, NUL 文字,あるいは 0177 以上のコードを含む非印字文字を読み落してはなりません. 唯一の意味のある例外は, これらの文字を扱えないある種のプリンタへの インタフェースのためのユーティリティに限られるでしょう. 可能な限り, マルチバイト文字を表現するバイト列に対しても, UTF-8 等のエンコーディングを使って, プログラムが正しく動作するように しましょう.
わざとエラーを無視したい時以外は, システムコールがエラーを
返しているかどうかを必ずチェックしましょう.
システムコールの失敗によるすべてのエラーメッセージには,
( perror あるいはそれと同等のものから得られる)システムの
エラーメッセージ文とファイル名,ユーティリティ名を入れましょう.
"cannot open foo.c" や "stat failed" だけでは十分ではありません.
malloc や realloc を呼ぶときは戻り値がゼロでないか必ずチェック
しましょう. 要求するメモリブロックの大きさの指定を小さくして reallocを
呼ぶときもチェックが必要です.
メモリブロックの大きさを2の累乗に切り上げるシステムでは, reallocに
指定するメモリブロックの大きさを小さくして呼び出すと, 異なるメモリブロックが
得られることがあります.
通常の Unix の realloc がゼロを返したときは,
メモリ領域を壊している可能性があります.
GNU reallocにはこの問題はなく, 失敗した場合も,もとのブロックを
変更しません. この問題は存在しないと考えて良いでしょう.
Unix でプログラムを動かすときに,この問題を避けたいのなら
GNU malloc を使えば良いのです.
free は解放された後のブロックの内容を変更してしまうと
考えなければなりません.
そのブロックから何か取りだしたいなら freeを呼び出す前にしましょう.
非対話的なプログラムで malloc に失敗した場合には,
致命的エラーとしましょう.ユーザからのコマンドを読み込むような,
対話的なプログラムの場合には, 実行中のコマンドを中断して, プログラムの
コマンド読み込みのループ部に制御を戻したほうが良いでしょう.
こうすれば, 他のプロセスを殺すなどして仮想メモリを空けて,
そのコマンドの再実行を試みることができます.
引数のシンタックスに合わない場合以外は,
引数を解析するには getopt_long を使いましょう.
プログラム実行中に書き込みが行われる静的記憶領域は,(宣言ではなく)Cコード中で 明示的に初期化します. Cの初期化宣言は読みだし専用データにだけ使いましょう.
不透明な Unix のデータ構造(ディレクトリ, utmp,カーネルメモリの
レイアウトなど )に対する低レベルインタフェースの使用は避けましょう.
それらは互換性があまりないからです.
あるディレクトリ内の全てのファイルを見つけたかったら
readdir やその他の高レベルのインタフェースを使いましょう.
これらは GNU により互換性がサポートされています.
シグナル操作機能として好ましいのは BSD 版の signal と
POSIX の sigaction 関数です. USG の signal
インターフェースは設計が劣ります.
今や, POSIX のシグナル関数を使うのがプログラムをポータブルに
する一番簡単な方法でしょう. signal を使うなら,
GNU/Linux で GNU libc バージョン 1 の場合は, `signal.h' の
代わりに `bsd/signal.h' を使うようにして, BSD の動作になるように
する必要があります. signal の動作が USG のものしかない
システムをサポートするか, あるいはあきらめるかは読者にお任せします.
エラーチェックで”起こりえない”条件を検知したら,単に中断しましょう. 通常,何かのメッセージを出力することには,意味がありません. これらのエラーチェックはバグの存在を示すものです.バグを修正したい人は ソースコードを読みデバッガを走らせないといけません.ですから,ソース内の コメントで問題について説明してください.関係のあるデータは変数の中にあるで しょうから,デバッガを用いて簡単に検査できるので,それらをどこかよそへ移す 事には意味がありません.
エラーの回数をプログラムの終了ステータスとしてはいけません. そうしても思った通りにいきません.終了ステータスは 8 ビットの値, つまり 0 〜 255 に限られるからです.プログラムを一回実行させただけで, 256 回エラーが発生する可能性があります. 256 を終了ステータスとして 返そうとしても,親プロセスには 0 が返されてしまいます.そうすると, そのプログラムはエラー無しで無事終了したものと見なされます.
一時ファイルを作成する場合は,まず環境変数 TMPDIR が
定義されているかどうかを調べる必要があります.定義されている場合には,
`/tmp' の代わりに, TMPDIR で指定されたディレクトリを使いましょう.
さらに,誰でも書き込み可能なディレクトリに一時ファイルを作成することに ついてはセキュリティ上の問題が発生する可能性に注意すべきでしょう. C 言語では,以下のような方法で一時ファイルを作成することでこの問題を 回避することができます.
fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600); |
あるいは,libiberty ライブラリの mkstemps 関数を
使うこともできます.
bash では,set -C とするとこの問題を回避できます.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ライブラリ関数はリエントラントになるよう努めてください.
関数が動的なメモリ獲得を必要としているならば,すくなくとも
malloc 自身の非リエントラント性以外の非リエントラント性を
避けるようにしましょう.
ライブラリの名前づけには,名前の衝突を避けるための規約があります.
ライブラリ用に2文字以上のプリフィックス名を選んでください. 外部関数と外部変数名は全てこのプリフィックスで始めるようにします. さらに,これらの名前はどのライブラリのメンバ(...o ファイル)にもそれぞれ 一個だけしか現れないようにすべきです. これは通常,それぞれの名前をそれぞれ別々のソースファイルに置くという意味です.
2つの外部シンボルがいつも一緒に使われ,片方をもう一方なしには使えない ようなプログラムは例外です. それらは両方とも同じファイルに入れます.
ユーザからエントリポイントとして見えてはいけない外部シンボルは, `_'で始まる名前にしなければなりません. `_' の後に そのライブラリ用に選んだ名前のプリフィックスを続けるようにして、 他のライブラリとの衝突を避ける必要があります。 こうしておけば,ユーザに見せて良いエントリポイントが あるファイルと同じファイルにいれておくことも可能です.
静的関数と静的変数は好きなように使って良いし, 特に名前付けの規約にも従う 必要もありません.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
コンパイラの出すエラーメッセージは次の形式にします.
ソースファイル名:行番号: メッセージ |
カラム番号を表示したい場合は次の形式を使います.
ソースファイル名:行番号:カラム: メッセージ |
行番号はファイルの先頭が 1 になるように始め, カラム番号は 行頭で 1 になるように始めます. (この規約は互換性のために選ばれました. ) カラム番号を計算する際には, スペースと ASCII の印字可能文字は 全て同じ幅を持ち, タブ・ストップは 8 カラム毎であるとしましょう.
コンパイラ以外の対話的でないプログラムの出すエラーメッセージは 次の形式にします.
プログラム:ソースファイル名:行番号: メッセージ |
これは該当するソースファイルがある場合です. 関係するソースファイルがない場合は次のように書きます.
プログラム: メッセージ |
カラム番号を表示したい場合は以下の形式を使います.
プログラム:ソースファイル名:行番号:カラム: メッセージ |
対話的なプログラム(端末からコマンドを読むようなもの)においては エラーメッセージ中にプログラム名を入れないほうがいいでしょう.どのプログラ ムが動いているかは,プロンプトあるいはスクリーンレイアウトにより示されています. (同じプログラムが端末以外のファイルから入力を読む場合,それは対話的では ありませんから,非対話的な形式でエラーメッセージを印字するの が最良です.)
メッセージの文字列がプログラム名とファイル名の後に続くときは, 大文字で始めてはいけません. また, ピリオドで終わってはいけません.
対話的なプログラムのエラーメッセージや使用法のメッセージは, 大文字で始めます.しかし,ピリオドで終ってはいけません.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
起動されるときのコマンド名によって, そのユーティリティ・コマンドの 振る舞いを変えるのはやめてください. ユーティリティを違う名前にリンクすると便利なことがあり, その場合でも振る舞いが変わらないようにすべきです.
その代わりに起動時のオプション,あるいはコンパイル時のスイッチ,あるいは その両方で振る舞いを選択できるようにします.
同様に, プログラムの振る舞いを出力先デバイスのタイプによって変えるのは やめてください. デバイスに依存しないことはシステムの設計の重要な 原則です. 単に, 誰かがたまにオプションを入力しなくても済むようにするために 妥協するのはやめてください. (端末を使っているときにエラー・メッセージの 構文を変えるのは構いません. 人々がそのことに依存するようなことのない, 副次的な問題だからです. )
出力先が端末の場合に適した動作と, それとは別に, 出力先がファイルやパイプの場合に適した動作があるなら, デフォルトは端末向けの動作とし, もう一方の動作は何かオプションを 指定したときに実行されるようにするのが良いでしょう.
互換性のために, ある種のプログラムでは出力先のデバイスに依存することが
要求される場合もあります. (出力デバイスに依存するプログラムの代表例である)
ls や sh が, 全てのユーザの期待する
通りに動かなかったら, 一大事でしょう.
そのような場合には, 我々は, 出力先デバイスに依存しない好ましい別のバージョン
のプログラムで補います. 例えば, 我々は dir という,
ls とほとんど同じプログラムを提供していますが,
デフォルトの出力フォーマットは, 常にマルチカラムのフォーマットにしています.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
グラフィカルユーザインターフェースを提供するプログラムを書く場合は, 機能的に何か別のものを必要とする(例えば,「コンソールモードで JPEG のイメージを表示する」など)のでない限り,X Windows と GTK ツール キットで動作するようにして欲しい.
さらに,その機能を制御するコマンド行インターフェースも提供して欲しい. (多くの場合,グラフィカルユーザインターフェースは,コマンド行プログラム を起動する独立したプログラムとすることが可能である.) これは,同じ作業をスクリプトからでも行なえるようにするためである.
また,CORBA インターフェース(GNOME から使うため),ライブラリインターフェース (C 言語から使うため),キーボード入力駆動とするコンソールインターフェース (コンソールモードからユーザが使うため)を提供することも 検討して欲しい.一度,機能そのものとグラフィカルユーザインターフェスが 動くようになれば,これらはそれほど大変な作業ではない.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムのコマンド行オプションは, posix ガイドラインに従うのが
良いでしょう.そのためにはオプションの解析時にgetoptを使うのが最も
簡単です.
GNU 版の getopt では, 特殊な引数`--'を指定しない限り,
引数の中のどこにオプションがあっても良いことにしています.
これは posix の仕様ではありません. GNU の拡張です.
Unix風の1文字オプションと同値のオプションを長い名前で定義してください.
このようにGNU はもっと親切になりたいと望んでいます. GNU の関数
getopt_long を使えば簡単です.
長い名前のオプションの利点の一つに,プログラム間で一貫性を保てることが あります. 例えば,"verbose" オプションを持つ GNU プログラムではいつでも, そのオプションは `--verbose' と綴られるとユーザが期待しても 良いようにすべきです. このような一貫性を達成するためには, 自分のプログラムのオプション名を選択するときに,共通の長いオプション名の 表があるので,見てください (see section 4.7 長いオプションの表).
普通の引数で与えられるファイル名は入力ファイルに限る, というのは良い考えです. 出力ファイルはオプション( なるべく `-o' か `--output')で あたえれば良いのです. 互換性のため,出力ファイル名も通常の引数で与えられるようにしたいと思った時は, 別の方法で指定するためのオプションも同様に提供しましょう. そうすれば GNU のユーティリティ間の一貫性が保たれ,ユーザが特別に 覚えなければならないことが少なくなるからです.
すべてのプログラムは, `--version' と `--help' の二つの 標準オプションをサポートしなければなりません.
--version
プログラム情報の一行目は他のプログラムがパースしやすいように してください. バージョン番号自体は, 一行目の最後の空白の後に 書きます. さらに, 次のような形式で, プログラムの正式な名前を書きます.
GNU Emacs 19.30 |
プログラム名は文字列定数にしてください. argv[0] から
求めてはいけません. というのは, プログラムのファイル名ではなく,
正式な名前を表示するのが目的だからです.
コマンドが PATH にあるものなら, 正確なファイル名を知る方法は
別にあります.
プログラムがより大きなパッケージの補助的なものなら, 以下のように, パッケージ名を括弧の中に示します.
emacsserver (GNU Emacs) 19.30 |
パッケージのバージョン番号とプログラムのバージョン番号が違っている 場合には, 閉じ括弧の前にパッケージのバージョン番号を入れましょう.
プログラムが入っているパッケージとは別に配布されているライブラリの バージョン番号についても表示する必要があるばあいは, ライブラリ毎にバージョン情報を一行ずつ追加表示しましょう. 追加する行は一行目と同じ形式を使ってください.
完全性を追及するためだけの理由で, プログラムが使う全ライブラリに ついて言及するのは避けてください. 役に立たない情報であふれるだけです. デバッグのために非常に重要だと判っているものだけについて, バージョンを 表示するようにしてください.
バージョン表示の後には, 著作権表示を出力します. 著作権表示が複数 ある場合は, 一行に一つずつ表示します.
その次には, プログラムがフリーソフトウェアであること, ある条件の元で コピーや変更を行って良いことを簡単に説明します. プログラムが GNU GPL で カバーされるものなら, この部分にその旨を宣言します. また, 法律で許される範囲で, 無保証であることも述べます.
最後に, プログラムの主要な著者名を挙げて, クレジットの表示としても良いでしょう.
以上の規則に則った例を以下にしめします.
GNU Emacs 19.34.5 Copyright (C) 1996 Free Software Foundation, Inc. GNU Emacs comes with NO WARRANTY, to the extent permitted by law. You may redistribute copies of GNU Emacs under the terms of the GNU General Public License. For more information about these matters, see the files named COPYING. |
もちろん, 自分のプログラムに合わせて変更すべき部分があります. 年, 著作権保持者, プログラム名, 配布条件への参照を埋め, 他の部分も必要に応じて変更してください.
著作権表示に示す年は, 最後に変更があった年を示すだけでかまいません. それ以前の変更を行った年を表示する必要はありません. 面倒なら, 著作権表示中にプログラム名を示す必要はありません. 既に一行目に示しています.
以上の行の翻訳は、著作権表示の有効性を保持しなければなりません see section 5.8 国際化)。翻訳に使用する文字セットが対応しているなら、 `(C)' は、以下のように、著作権記号で置き換える必要があります。
(正式な著作権記号、文字 C を円の中に置いたもの) (C)
"Copyright"という語は、そのまま英語で書いて下さい。これを他の言語に 翻訳しては行けません。国際条約は、英単語 "Copyright"を認識しますが、 他の言語に翻訳したものは法的な意味を持ちません。
--help
オプション `--help' の出力の最後に,バグレポートの送り先のメールアドレスを 書いた行を一行含めてください. 以下の形式で書いてください.
Report bugs to mailing-address. |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
次の表は,GNU プログラムで使われている長い名前のオプションの一覧です. まだ不完全なものですが, 我々は新しいプログラムと互換性のあるオプションを すべて列挙することを目指しています. この表にまだ入っていない名前を使ったら, 意味を書いたリストを bug-standards@gnu.org に送ってくれれば, われわれはこの表を更新します.
tar の `-N' .
du, ls, nm, stty, uname, unexpand
の `-a' .
diff の `-a' .
ls の `-A'.
etags, tee, time の `-a',
tar の `-r'.
cp の `-a' .
shar の `-n' .
m4 の `-l' .
diff の `-a' .
gawk の `-v' .
recode の `-a' .
wdiff の `-a' .
ptx の `-A' .
wdiff の `-n' .
ctags の `-B' .
shar の `-f' .
tac の `-b' .
cpio と diff の `-b' .
shar の `-b' .
shar の `-b' .
cpio と tar で使用.
head と tail の `-b' .
ptx の `-b' .
head, split, tail の `-c' .
etags の `-C' .
tar の `-A' .
chgrp と chown の `-c' .
ls の `-F' .
recode の `-c' .
su の `-c',
GDB の `-x' .
tar の `-d' .
gawk で使用.
tar と shar の `-Z' .
tar の `-A' .
tar の `-w' .
diff で使用.
gawk の `-W copyleft' .
ptx, recode, wdiff の `-C',
gawk の `-W copyright'.
who の `-q' .
du の `-l' .
tar と cpio で使用.
shar の `-c' .
ctags の `-x' .
touch の `-d' .
m4 の `-d',
Bison の `-t' .
m4 の `-D' .
ctags の `-d' .
tar の `-D' .
chgrp, chown, cpio, du,
ls, tar の `-L' .
du の `-D' .
recode の `-d' .
look の `-d' .
tar の `-d' .
csplit の `-n' .
ls では, 中身ではなくディレクトリ自身を表示することを意味する.
rm と ln では, ディレクトリへのリンクを特別扱いしないようにする.
strip の `-x' .
strip の `-X' .
diff の `-e' .
csplit の `-z' .
wdiff の `-x'.
wdiff の `-z'.
diff の `-N' .
xargs の `-e' .
makeinfo で使用.
m4 の `-o' .
ls の `-b' .
tar の `-X' .
xargs の `-x' .
unshar の `-e' .
diff の `-t' .
sed の `-e' .
nm の `-g' .
cpio の `-i',
tar の `-x' .
finger の `-f' .
su の `-f' .
m4 の `-E' .
info, gawk, Make, mt, tar の `-f',
sed の `-n',
touch の `-r' .
gawk の `-F' .
ls の `-F' .
tar の `-T' .
makeinfo で使用.
ptx の `-F' .
tail の `-f' .
makeinfo で使用.
cp, ln, mv, rm の `-f' .
shar の `-F' .
ls, time, ptx で使用.
m4 の `-F'.
ptx の `-g' .
tar の `-x' .
ul の `-i' .
recode の `-i' .
install の `-g' .
tar と shar の `-z' .
m4 の `-H' .
objdump と recode の `-h' .
who の `-H' .
shar の `-d' .
ls の `-q' .
makeinfo で,HTML を出力する.
who の `-u' .
diff の `-D' .
ls の `-I',
recode の `-x' .
diff の `-w' .
ls の `-B' .
diff の `-B' .
look と ptx の `-f',
diff とwdiff の `-i' .
ptx の `-i' .
etags の `-I' .
tee の `-i' .
diff の `-I' .
diff の `-b' .
tar の `-i' .
etags の `-i',
m4 の `-I' .
tar の `-G' .
expand の `-i' .
diff の `-T' .
ls の `-i' .
cp, ln, mv, rm の `-i',
m4 の `-e',
xargs の `-p',
tar の `-w' .
shar の `-p' .
date で使われている.
csplit の `-k'.
du と ls の `-k' .
etags の `-l'.
wdiff の `-l'.
shar の`-g' .
split の `-C' .
split, head, tail で使用.
cpio の `-l' .
gawk で使用.
cpio の `-t',
recode の `-l' .
tar の `-t' .
ls の `-N' .
su で使用.
ptx の `-M' .
hello と uname の `-m' .
cpio の `-d' .
xargs の `-n' .
xargs の `-n' .
xargs の `-l' .
xargs の `-P' .
who の `-T' .
who の `-T' .
diff の `-d' .
shar の `-M' .
install, mkdir, mkfifo の `-m' .
tar の `-m' .
tar の `-M' .
m4 の `-L' .
shar の `-a' .
shar の `-w' .
shar の `-x' .
wdiff の `-3'.
touch の `-c' .
etags の `-D' .
wdiff の `-1'.
cp の `-d' .
wdiff の `-2'.
shar の `-P' .
gprof の `-e' .
etags の `-R'.
nm の `-p' .
makeinfo で使用.
gprof の `-a' .
gprof の `-E' .
shar の `-m' .
makeinfo で使用.
emacsclient で使用.
info の `-n' .
uname の `-n' .
cpio の `-f' .
objdump の `-n' .
xargs の `-0' .
cat の `-n' .
cat の `-b' .
nm の `-n' .
cpio と ls の `-n'.
tar の `-o' .
tar, cp, du の `-l' .
ptx の `-o'.
gprof の `-f' .
gprof の `-F' .
getopt, fdlist, fdmount,
fdmountd, fdumount の `-o' .
shar の `-o' .
rm の `-o' .
unshar の `-c' .
install の `-o' .
diff の `-l' .
makeinfo で使用.
mkdir と rmdir の `-p' .
ul の `-p' .
cpio の `-p' .
finger の `-P' .
cpio と tar の `-c' .
gawk で使用.
m4 の `-P' .
csplit の `-f' .
tar と cp で使用.
su の `-p' .
cpio の `-m' .
tar の `-s' .
tar の `-p' .
diff の `-l' .
cmp の `-L' .
nm の `-o' .
nm の `-s' .
wdiff の `-p'.
ed の `-p'.
shar の `-X' .
shar の `-Q'.
ls の `-Q' .
diff の `-n' .
gawk で使用.
tar の `-B' .
tar の `-R' .
chgrp, chown, cp, ls, diff, rmで使用.
makeinfo で使用.
ptx の `-r' .
tac と etags の `-r' .
uname の `-r' .
m4 の `-R'.
objdump の `-r' .
cpio の `-r' .
xargs の `-i' .
diff の `-s' .
cpio の `-a' .
ls と nm の `-r' .
diff の `-f' .
ptx の `-R' .
tar の `-s' .
tar の `-p' .
stty の `-g' .
ptx の `-S' .
du の `-S' .
tac の `-s' .
recode で,シーケンスを渡すファイルやパイプを選択するのに
使われる.
su の `-s' .
cat の `-A' .
diff の `-p' .
cat の `-E' .
diff の `-F' .
cat の `-T' .
ls の `-s' .
ls で使用.
gawk の `-W source'.
tar の `-S' .
diff の `-H' .
unshar の `-E' .
shar の `-L' .
cat の `-s' .
wdiff の `-w'.
wdiff の `-y'.
tar と diff で, ディレクトリ中のどのファイルから処理を
開始するかを指定するのに使用.
wdiff の `-s'.
shar の `-S' .
recode の `-s' .
install の `-s' .
strip の `-s' .
strip の `-S' .
shar の `-s' .
cp, ln, mv の `-S'.
csplit の `-b' .
gprof の `-s' .
du の `-s' .
ln の `-s' .
objdump で使用 .
m4 の `-s' .
uname の `-s' .
expand と unexpand の `-t' .
ls の `-T' .
tput と ul の `-T' .
wdiff の `-t'.
diff の `-a' .
shar の `-T' .
ls と touch で使用.
tar の `-O' .
du の `-c' .
ranlib と recode の `-t' .
m4 の `-t' .
hello の `-t',
gawk の `-W traditional',
ed, m4 と ptx の `-G' .
ctags の `-t' .
ctags の `-T' .
ptx の `-t' .
tar の `-z' .
cpio の `-u' .
m4 の `-U' .
nm の `-u' .
cp, `ctags', `mv', `tar' の `-u'.
gawk で使用. `--help' に同じ.
shar の `-B' .
shar の `-V' .
tar の `-W' .
cp, ln, mv の `-V' .
ctags の `-v' .
tar の `-V' .
shar の `-l' .
ls と ptx の `-w' .
ptx の `-W'.
who の `-T' .
gprof の `-z' .
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムのメモリ使用量が数メガバイト程度なら,使用量を減らそうと四苦八苦する 必要はありません.例えば,数メガバイトを越えるファイルの取扱いが 何か他の理由で難しければ,ファイル全体をメモリに読み込んで取り扱うのが 妥当でしょう.
しかし, cat や tail のように, 非常に大きなファイルに対しても
問題なく使える必要のあるプログラムについては, 取り扱えるファイルの大きさを
人為的に制限するような細工を使うのは避けるべきです.
行単位に動作するプログラムで,ユーザが指定した任意の入力ファイルに
対して適用可能であれば,メモリ中には一行分だけ保持すべきです.
これはそれほど難しいことではないし,ユーザはメモリに一度に入り切らない
ぐらい大きなファイルが取り扱えることを望むものだからです.
読者の作るプログラムが, 複雑なデータ構造を要するものなら,それを
動的にメモリ中に作り, malloc がゼロを返した場合には致命的
エラーとしましょう.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムは,`/usr' と `/etc' が読み出し専用ファイルシステム であっても動作するよう用意しておかなければならないでしょう. つまり,プログラムがログファイルや,ロック用ファイル,バックアップ用 ファイル,ソースファイル,あるいはそれ以外のファイルを内部的な 目的で変更することがあるなら,これらのファイルは `/usr' と `/etc' に置いてはいけません.
例外が二つあります.`/etc' はシステムの構成情報を置くのに使われます. プログラムの仕事がシステム構成情報を更新することにあるなら,そのプログラムが `/etc' にあるファイルを変更するのは妥当でしょう. また,ユーザがあるディレクトリにあるファイルを変更することを 明示的に要求したなら,プログラムが同じディレクトリに他のファイルを 置くのも妥当でしょう.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |