Next: Particular Functions, Up: Library Functions
ほとんどの通常の関数は,足りない,またはバグがある,またはアーキテクチャ によって制限があるはずです.このセクションでは,これらの移植性の問題を目 録にしようと思います.定義からすると,このリストは常に追加が必要です.で きるだけ完全なものを保つために,我々への手助けをお願いします.
exit
exit
がint
を返すものがあることを御存知です
か?これは,exit
のほうがvoid
より時代が古く,int
を
返すという伝統が長い間あったためです.
putenv
putenv
は与えられた文字列を直接environ
に書き込む
ように指定していますが,システムによってはその代わりにコピーするものもあ
ります(例えば,glibc 2.0やBSD).そして,コピーが作成されたとき,
unsetenv
はそれを解放し,メモリリークの原因になります(例えば,
FreeBSD 4がそうです).
POSIXでは,putenv("FOO")
は‘FOO’を環境変数から削除するように
指定していますが,システムによっては(例えばFreeBSD 4),こうならないので,
代わりにunsetenv
を使用して下さい.
MINGWでは,putenv("FOO=")
の呼び出しで,空の値を挿入する代わりに,
‘FOO’を環境変数から削除します.
signal
ハンドラsignal
はvoid
の型を返す関数へのハンドルを受け取ります
が,古いシステムには,代わりにint
を要求するものもあります.実際に
返されるint
の値を利用しませんが,これは関数のプロトタイプの要求が
異なるだけです.
現在知っているシステムはすべてvoid
を受け取ります.おそらく,
int
がK&R Cでサポートされていたのですが,もちろんvoid
は利用
可能ではありませんでした.AC_TYPE_SIGNAL
(see Particular Types)は,すべての状況で正しい型を構築するために使用することが可能です.
snprintf
snprintf
とvsnprintf
は出力を切捨て,生成された出力が必要と
するバイト数を返すことになっています.古いシステムでは切り捨てられた長さ
を返したり(例えば,GNU Cライブラリ2.0.xやirix 6.5),負の
値を返したり(例えば,より古いバージョンのGNU Cライブラリ),切
り捨てられなかったバッファの長さを返したり(例えば32ビットのSolaris 7)し
ます.また,バグの多い古いシステムにはバッファの長さとオーバーランを無視
するもの(例えば64ビットのSoraris 7)もあります.
sprintf
sprintf
とvsprintf
は書き込まれたバイト数を
返すことになっていますが,古いシステム(例えばSunOS 4)ではその代わりにバッ
ファへのポインタを返すものもあります.
sscanf
sscanf
は入力文字列が(たと
えそれが実際には変更されなくても)書き込み可能であることを要求します.こ
れは,gccは通常,固定文字列を読み込み専用のメモリに書き込むの
で(see Incompatibilities of GCC),それを使用するとき問題
になるはずです.場合によっては,フォーマット文字列が明らかに読み込み専用
であっても問題になるはずです.
strnlen
strnlen ("foobar", 0) = 0 strnlen ("foobar", 1) = 3 strnlen ("foobar", 2) = 2 strnlen ("foobar", 3) = 1 strnlen ("foobar", 4) = 0 strnlen ("foobar", 5) = 6 strnlen ("foobar", 6) = 6 strnlen ("foobar", 7) = 6 strnlen ("foobar", 8) = 6 strnlen ("foobar", 9) = 6
sysconf
_SC_PAGESIZE
は標準ですが,古いシステム(例えばHP-UX 9)には,代わり
に_SC_PAGE_SIZE
が存在します.これは#ifdef
でテスト可能です.
unlink
unlink
は開かれているファイルへのハンド
ルがなくなった後でファイルを削除するように述べられています.全てのOS が
この動作をサポートしているわけではありません.そのため,システムが
unlink
を提供している場合でも,開いているファイルに対して呼び出し
ても大丈夫だと仮定した移植は不可能です.例えば,Windows 9xとMEでは,その
ような呼び出しは失敗します.DOSは可能ですが,OSが削除した後に
ファイルへの書き込みが終了するので,ファイルシステムが駄目になります.
unsetenv
unsetenv
が利用不可能ですが,putenv
で上述したよ
うに,変数‘FOO’はputenv("FOO=")
の呼び出しで削除可能です.
va_copy
va_list
をコピーするためva_copy
を提供して
います.古い環境でも利用可能かもしれませんが,おそらくは
__va_copy
(例えば厳密なC89モード)でしょう.これらは#ifdef
でテスト可能です.memcpy (&dst, &src, sizeof(va_list))
で代替する
ことで最大の移植性となるでしょう.
va_list
va_list
はポインタである必要はありません.struct
(例えば
Alphaのgcc)にすることが可能で,それはNULL
では移植性が無
いことを意味します.配列(例えばPowerPCでコンフィグレーションされた
gcc)も可能で,それは関数のパラメータとして効果的に参照呼び出し
が可能であり,ライブラリルーチンで呼び出しが返す値を修正する可能性がある
(例えばGNU Cライブラリ2.1のvsnprintf
)ことを意味します.
>>
>>
はハイビットを複製し,いわゆる“算術”
シフトになります.しかし,ISO Cの標準ではその動作を要求していないので,
注意すべきです.ネイティブの算術シフトが無いプロセッサ(例えばCrayベクター
システム)では,符号無しのシフトと同様に,ゼロビットがシフトインされる可
能性があります.