
okuの日記: あれ、ctype.hのisXXXXXって「関数」になったんだっけ? 4
日記 by
oku
ちょっと気になるところがあって JISC で JIS X3010を読み直したのですが、ctype.h の isXXXXX って「関数」と明記されているようですね。
ctype.h の関数群は「マクロでもよい」(故に isXXXXX への関数ポインタを取れるとは限らない) という記述をどこかで読んだような記憶があるのですが、何かの記憶違いでしたかね...? (実際、昔の Solaris 7~9 頃の実装は引数付マクロだった筈...)
# C99 で変わったのかな?
7.1.4参照 (スコア:1)
原則として標準ライブラリの関数は、追加的にマクロとして実装してもいい。
ただしその場合でも本物の関数による実装も与えなければならない(したがって関数のアドレスは必ず取れる)。古いSolarisの実装が本物の関数による実装も与えていたかどうかは知らないが、もし与えていなかったら規格違反。
Re:7.1.4参照 (スコア:1)
情報ありがとうございます。 後で JISC を確認しておきます (∵手元に JISC の PDF 画像を読む環境がない)。
記憶で書いているので当時の Solaris (7〜9) の実装が正確にどうだったかという確信はないのですが、#ifdef 次第で関数版を選べるようになっていたような憶えがあります。 引数付きマクロ版の方も内部関数を呼び出すようになってはいたと思いますが、(例えば) isalpha と isalnum が同じ内部関数を違う引数で呼び出すような仕組みになっていたのではなかったかなぁ、と (そのまま関数ポインタを取ると同じ値になってしまうし、関数ポインタのプロトタイプ型が (int*)(int) ではなくなっていたような...)。
Re: (スコア:0)
> そのまま関数ポインタを取ると同じ値になってしまうし、関数ポインタのプロトタイプ型が (int*)(int) ではなくなっていたような...
なんで関数のアドレスを取るのにヘッダの中身という実装詳細を見ること前提なの? isalnumだったら「isalnum」と関数名だけ書いて関数のポインタにならなきゃダメに決まってるだろ。ついでに言うと、規格では (isalnum)(c); のように書けば関数版を呼び出せることも要求している。
Re:7.1.4参照 (スコア:1)
何度も繰り返しますが、当時の記憶を元に書いているので (1)記憶違い、 (2)脳内美化、 (3)そもそも誤読、 (4)その他諸々、 による誤差があり得ることを前提の上でお願いします。
当方の (呼出し元のプログラムを書く) 立場から言えば「#include <ctype.h>」して利用するから、です。 当時の SUN の立場は知りません (当方の勘違いかも知れないし、SUN が何かの後方互換性への配慮で、妙な引数付マクロ版をデフォルトにしていたのかも知れません。 元のポストに書いた通り、#ifdef 次第で引数付マクロ版ではなく真の関数版を呼べたような記憶はあります。 あくまで記憶ですが)。
私の望みもそちらです。 本当は昔からデフォルトがそうなっていて欲しかったんだけど、当時は違っていて残念な思いをしたんだけどなぁ、今は変わったのかな?というのが本意です (最初のポストからはそう読み取れないですね、失礼)。
それこそ記憶で書いているので、ひょっとしたら LSI C-86 とか libc5 を刺すべきところ、Solaris を誤爆している可能性もありますけどね。 (^_^;