[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:000461] Re: proto2c



豊田です。

> 高橋くん>
>  > 結局 C との絡みで考えると,Fortran での終端文字は何か?
>  > という問題になるように思うんですが.
>
> Fortranでは文字の終わりの判別を null とかいった特定の文字で行っ
> ているのではないようです。

おっしゃるとおり、終端文字などというものはありません。そもそも終端なんて概
念がありえないのです。まさか堀之内さんはおわかりだと思っていたのですが、不
安になってきたので念のため。

> f2cしたソースでは文字列引数があると、
> その文字列の長さを与える引数が新設されます。よって fortran の実
> 装では、文字列の長さを与える隠れ引数があるんだろうと思います。

「(サブルーチン引数ではない)すべての文字型変数について、文字列は長さと文
字格納場所の対で保持されている」という見解でしたら誤りです。そういうものが
ほしかったら Pascal を使うとか、拙作 ISO_VARYING_STRING をもっていくとか
してください。

FORTRAN の文字型は固定長です。つまり、記憶領域だけみると長さ1の文字型の配
列と同じです。サブルーチンの中で長さを変えることはできません。

文字型代入文で両辺の長さが違うことがありますが、左辺が短い場合切り捨てられ
るのは堀之内解釈であっているようですが、左辺が長い場合は足りない部分にすべ
て空白が補われます。あくまで左辺の長さの値が生成されて書き込まれますので、
文字型変数の長さが変化することはありません。

長さが変化したことを伝える必要がないので、本来の文字列の後に何か特別なバイ
トを書き込むことはしません。必要がないだけじゃなくて、そのような実装は記憶
列結合の規則から禁止されます。なので f2c なら C プログラマにフレンドリーな
ことをしてくれるとかいった淡い期待をしてはいけません。

つぎにサブルーチン引数の結合規則を理解される必要があります。

たぶん CHARACTER*(*) と宣言したときは理解しやすくて、サブルーチンにとって
も呼び出し元で与えた長さの文字列ということになります。

サブルーチン引数を固定長で宣言すると、サブルーチンの中での長さはその長さで
固定になります。サブルーチンで CHARACTER*14 の引数だといってしまえば呼び
出し元で何を与えようがサブルーチンにとっての長さは14です。たとえば呼び出し
元では CHARACTER*16 の文字変数があったとすると、サブルーチン内で値を代入
しても最後の 2 文字は書き換えられません。この場合は呼び出し元での長さ指定
は無視されます。なので、サブルーチンが期待している長さより短いものを与える
と危ない。

> null文字は何かという問題はあります。文字列を返す Fortran サブルー
> チンが内部で、
>
>   cresult(1:5)='hello'
>
> 的な代入をしてれば、6文字目以降は C の null のままでしょうし、
>
>   cresult = 'hello'
>
> なら Fortran なりの null を入れてくれるのでしょう。

そういう意味では cresult が 6 文字以上なら 6 文字目以降はサブルーチンが
文字長だと思っている長さまでずっと空白を入れます。空白とは具体的には私の
知るすべての処理系で ASCII SPACE を入れます。6 文字以上期待しているのに
5 バイトしか与えなかったら、たいていすごく嫌なことが起こるはずです。

    もちろん引数リストを調べて安全側に倒すという設計もありえるとは思うの
    ですが、たぶん f2c や g77 はそうなっていなかったはず。

そして、NUL じゃないありふれた文字を入れるという仕様は堀之内さんの長さ判定
アルゴリズムを非常に信頼性に欠けるものにします。この問題は GETENV とか
GETARG を ISO_VARYING_STRING 対応にしようと思ったときにぶち当たりました。
--
arte, non vi.
豊田英司: TOYODA Eizi
mailto:toyoda@xxxxxx