処理系 - みる会図書館


検索対象: 月刊 C MAGAZINE 1992年6月号
188件見つかりました。

1. 月刊 C MAGAZINE 1992年6月号

これまて℃プログラムの検査は多くの場合 C コンパイラて、行われていた。なかには UN IX の lint などの検査ユーティリティを使う場 合もあったろうが , これらの検査は基本的 に文法 , つまり構文規則にあっているかを チェックするものだった。そのため , Fig. 12 のように構文的には許されても結果の動作 が処理系により異なる部分 ( いわゆる「処理 系定義」項目 ) などのチェックは難しかった。 ISO の規格書の巻末付録には , 「未規定」 , 「未定義」 , 「処理系依存」の各項目がまとめ られている。プログラム作成時に常にその 付録を参照しそこに列挙されている項目に 依存する部分を排除すればよいのだが , 項 目数が多いためもあり困難なことて、ある。 しかも Fig. 12 の場合 , 変数の値が特定の条 件に該当するときだけ「処理系定義」になっ たりするのて、 , 静的なチェックはますます 困難て、ある。 C モテルインプリメン テーションチェッ 「厳密に規格に合致したプログラム」て、あ ることを完全に検査し , こういった状況を 解決しようとして開発されたのが C モデルイ ンプリメンテーション (Model lmplementa tion for C) チェッカて、ある。このソフトウ ェアは , 英国 Knowledge Software 社が BS I との契約に基づき開発したものて、 , 著作権 などの権利は Knowledge Software 社に属 する。 BSI は C コンパイラの検査だけて、なく , C プログラムの検査についても考慮していた のて、ある。もっとも C コンパイラ用のテスト スイート自体の検査や検討にもこのような チェッカが必要て、はあった。そのためもあ り , このチェッカについては当初 BSI など各国 の標準化母体からの販売だけが考えられて いたが , 現在て、は一般の代理店経由て、も販 売されている。日本て、の代理店は ( 株 ) アド バンスド・データ・コントロールズ ( 電話 0 3 ー 3576 ー 5351 ) て、ある。 C MAGAZINE 1 的 2 6 このチェッカは基本的には , C コンパイラ / リンカ / ライプラリそしてインタブリタて、構 成される「規格に合致したホスト処理系」て、 ある。単に ISO 規格て、要求されることを実装 するだけて、はなく , 一切の拡張をしないと いう方針をベースとしている。そのため対 象プログラムを検査し , そこに含まれる「厳 密に規格に合致したプログラム」性を阻害す る要因すべてを検出する機能を持っている。 もちろん「未規定」 , 「未定義」 , 「処理系定義」 の各動作や構文ェラー , 制限違反も検出さ れる。この検出はコンパイル時のみならず , リンク時や実行時にも行われる。もちろん コンパイラ部て、検出される項目が圧倒的に 多いのだが , それらを検査する機能を厳密 に実現するためには , 通常のコンパイラ作 成とは異なるアプローチが必要て、あった。 こて、 , このチェッカのコンパイラ部 (m cc ) 開発て、使われた基本的なアプローチを紹 介しておこう。 ①旧 0 規格でのすべての要求が実装されてい ることを明確にすること これには , ISO 規格て、の要求項目をすべて 明確にすることと , その要求を満たしてい ることの確認が必要て、ある。そのために まず ISO 規格の記述を要求ごとに分解し , そ れぞれにユニークな番号をつけた。そして mcc に含まれるすべての if 文に参照番号をつ けた。この番号は規格て、の要求項目か内部 ドキュメントを参照するためのものて、ある が , 全部の番号を集計すれば規格て、の要求 項目 ( ュニークな番号 ) すべてをカバーして いるかどうかが確認て、きる。 ②社内テストでは mcc のすべての文を実行す 実際にはすべての基本プロックの実行を チェックしたのだが , 各基本プロックには 入口と出口がそれぞれひとつだけしかない このような基本プロックには , ディスクフ ルて、ファイル書き込みがて、きないときだけ 実行される , というものもある。そのため 当初のテストカバレッジは 80 % 程度だった その後こういったプロックを発見する手法 を確立し , それをテストて、きるデータが作 成て、きたのて、 , 最終的なプロックレベルて、 のテストカバレッジを 99.6 % まて、にて、きた つまりいかなる場合にも実行されないよう なプロックを , mcc はほとんど ( 0.4 % しか ) 含まないことになる。 ③処理をできるだけ単純化し , 最適化のよ うにバグの原因になる処理は取り込まな い まず mcc が出力する ( オプジェクト ) ファイ ルを C 専用のものとし , コンパイラて、の処理 を軽減した。実際に出力されるコードと c ソ ース内容とは 1 対 1 に対応している。そのた め出力されたコードから , 元のソース中の 式や文を再生することも可能て、ある。この 再生されたソースと元のソースを比較すれ ば , バグも容易に発見て、きる。 またこのチェッカて、はコンパイルしたプ ログラムの実行速度やサイズ , それにター ゲット CPU への配慮が不要なのて、 , 最適化 や拡張を取り込んて、いない。これによりか なりの数の潜在的なバグを避けることがて、 きたはずて、ある。 ④他社が開発したテストスイートで検査す る 一般にバグのないソフトウェアは存在し ないといわれるが , ソフトウェアを作成す る人が異なればバグも異なるのが普通て、あ る。そのため , このチェッカとは別に開発 されたテストスイートを使って検査するこ とが , チェッカ開発者にとってもスイ 開発者にとってもメリットがあった。この チェッカの開発時期がほかのスイートの開 発時期とほば一致していたことも幸いし , スイートべンダからの積極的な協力も得ら れた。 本稿に冒頭て、述べた Plum HalI VaIidati on Suite もそのひとって、 , このスイートを コンパイルしたときの最終的な ( 基本プロッ クの ) カバレッジは約 84 % て、あった。 Know ledge Software 社はもうひとっ別な商用ス ィートて、もテストを行ったが , その最終結 果も約 84 % て、あった。当然のこととして ,

2. 月刊 C MAGAZINE 1992年6月号

C 概観 している読者も多いことだろう。 話がまた横道にそれるが , この「 K & R 準拠」 とは ' 82 年に出版された , Kernighan と Ritc hie による [fThe C programming languag e 』中の AppendixA に基づくことを意味し ていた。しかしこの本自体はプログラミン グのためのものて、あり , 言語の仕様書て、は ないのて、 , AppendixA に記述されているリ ファレンスもかなり曖昧なものだった。 ついて、にいえば , この本の第 2 版が「 ANS I 規格準拠」ということて、 ' 89 年に出版されて いるが , この第 2 版もあくまて、もプログラミ ングのための本て、あることを注意しておき たい。この第 2 版は ANSI あるいは ISO 規格の 雰囲気を知るのには役立つかもしれないが , TabIe 3 c プログラムの分類 分類 規格のすべてを正確に知るには不十分て、あ る。 さて今後は多くの C コンパイラが ISO 規格 べースになり , ポータブルなプログラムが 簡単に作成て、きるようになるだろう。つま りパソコンて、もワークステーションて、も , さらにはメインフレームて、も , どのような コンパイラて、もコンパイルて、きるプログラ ムが簡単に作成て、きることになる。このこ とはソフトウェアの生産性向上に役立つが , しかしここて、は , たとえば X Window 用の アプリケーションをそのまま Windows 向け に使用するなどということを考えているの てはない また単にファイルをオープンす る場合て、も , ストリームペースのものとレ 内容 コードベースのものなどの違いにより , とえば f 叩 en 関数の第 2 引数が , fopen ("file. dat' "rb, recI=256") た 厳密に規格に合致したプロ旧 0 規格内の機能だけを使用したプログラム。処理系が独自に提供する拡張機 グラム 能を一切使用してはならない。また規格で「未規定」 , 「未定義」「処理系定義」と される項目に依存してはならない。さらに規格が処理系に要求している最小の 限界を越えてもならない。 規格に合致したプログラム「規格に合致した処理系」で問題なく処理できるプログラム。このプログラムは それ以外 分類 TabIe 4 C 処理系の分類 「処理系定義」項目など処理系固有の動作に依存してもよい。 上のいずれにも該当しないプログラム。たとえばある処理系では問題なくコン バイルできるが , ほかの「規格に合致した処理系」ではコンバイルできないよう なプログラム。 内容 規格に合致したホスト処理任意の「厳密に規格に合致したプログラム」を問題なく処理する。これは単に工 系 ラーなくコンバイルできることだけを指すのではなく , コンノヾイル結果の動作 も保証することを指す。 規格に合致したフリースタン一部のライプラリ機能を除き , 任意の「厳密に規格に合致したプログラム」を問 ティング処理系 それ以外 題なく処理する。この処理系はおもに組み込み用プログラムのためのものなの で , 入出力などのライプラリをサポートしないこともある。 上のいずれにも該当しない処理系。つまり一部の「厳密に規格に合致したプロ グラム」が処理できないような処理系。たとえは規格の ( 言語仕様の ) 一部を取 り込んでいないような処理系。 というように拡張されている可能性もある。 あるいは第 1 引数のファイル名も環境によっ て異なるかもしれない こういった動作環境 , すなわちターゲッ ト環境上の違いをコンパイラの仕様て、吸収 しようとしても無理て、あり , あくまて、も環 境に依存しない処理部分だけがポータブル プログラムの対象なのてある。このような 部分についてだけて、もポータブル性が保証 されれば , 構造がうまく設計されたプログ ラムて、は大いに役立つ。とくに多様なプラ ットホームを対象とするソフトウェアを開 発・保守する者にとって , このポータブル 性の保証は重要て、ある。 ところて、 ISO 規格て、は , このポータブル 性 , すなわちポータビリティがどのように 扱われているのだろう。現在の規格て、は C プ ログラムを , 「厳密に規格に合致したプログ ラム」 (strictly conforming program) , 「規 格に合致したプログラム」 (conforming pro gram), そしてそれ以外のプログラム , の 3 種類に分類している。 一方 , C コンパイラなどの処理系は「規格 に合致したホスト処理系」 (conforming hos ted implementation) , 「規格に合致したフ リースタンディング処理系」 (conforming f reestanding implementation) , そしてそれ 以外の処理系の 3 種類に分類されている。ま たいずれの処理系に対しても , 規格中て「処 特集第 3 の標準』 S C 概観 49 ム」てあることの検査てある。 になるのが「厳密に規格に合致したプログラ こて、問題 その結果の動作が保証される。 「規格に合致した処理系」て、のコンパイルと 種のプログラムが作成て、きれば , すべての に規格に合致したプログラム」てある。この タビリティを最大限に追求て、きるのは「厳密 ある。これらの表からわかるように , ポー 分類をまとめたものが Table 3 と Table 4 て、 キュメント化が要求されている。これらの 理系定義」とされている全項目に関してのド

3. 月刊 C MAGAZINE 1992年6月号

、、 $ ク , あるいは漢字が含まれているソースコ との互換性を考えて , ng の、、 file-io-code' これが , 1 バイト , 2 バイド混在の原稿にして ードは , 「規格厳密合致プログラム」とはいえ をシフト JIS て、はなく JIS に設定している。と いたらさらに頭を悩まさなければならなかっ たて、あろう。 ころが , この前の段落を書き終えたとき , ヒ ず , 移植性がない ) 。 このとき作った修復用のプログラムがまさ また , ソース文字集合に含まれる多バイト ョンな拍子て、 , ファイルが壊れてしまったの て、ある。原稿の途中だけ数十ページ分文字化 に , 前の段落て、述べた「漢字イン , 漢字アウ 文字は , Fig. 5 に示す文脈て、しか使用て、きな トのようなシフトシーケンスがあるような文 い ( ただし , 変数名 , 関数名 , ラベルなどに けしてしまったのだ。 字コード体系を採用している処理系て、は , さ 漢字などの多バイト文字を使うことはて、きな 締め切りもすぎてしまっており , 一時は , 呆然自失の状態て、あったが , 気を取り直し , らに , テキスト処理が複雑になってしまう」 例て、ある。 急遽 , ファイルコードをへキサダンプするツ このように規定されたことにより , the S 参考のために , List 1 にその修復用のプロ ールを作り , 中を覗いてみたら , おかしなこ tandardC て、は , 漢字を含んだ文字列を扱え とが起こっていた。各行の最後の 1 文字の第 グラムを示しておく。これは , pc ー 9801 ノー るようになったが , 漢字を含んだテキストを 2 バイト目だけが , 次の行の最初の 1 文字目の トの上に載せた g032 十 djgcc て、コンパイル 処理するプログラムを C 言語て、記述するに 直前に移動していたのて、ある。そのため , そ し , 実行させた。ただし , これは , 応急処置 は , これだけの仕様て、は不十分なのはいうま れ以降の文字が正しい 2 バイトの組み合わせ なのて、 , 決してよいプログラムて、はない。念 て、もない。なぜなら , もはや , 「 1 文字 = = 1 て、はなく , 隣接している文字の半分ずつのバ バイト」の関係は成立しないため , 従来の AS のため・・ イトが組み合わさって文字化けしてしまって CII コードを処理するように , 1 文字単位のポ ワイ。文字 いたのて、ある。 インタ操作が行えないからて、ある。 これを修復するには , 各行の最初にある 3 また , 漢字イン , 漢字アウトのようなシフ バイトのシフトシーケンス直後の 1 バイト ( 直 トシーケンスがあるような文字コード体系を このような状況を解決するために提案され 前の行の最後の文字の片割れ ) を前の行の最 採用している処理系て、は , さらに , テキスト たのが , ワイド文字て、ある。ワイド文字は , 後の 3 バイトのシフトシーケンスの直前に移 拡張文字集合の要素 ( 文字 ) を表現するのに十 処理が複雑になってしまうて、あろうことは想 動させてやる , というややこしいことをしな 分な大きさの型 wchar t のデータて、ある。 w 像に難くない 余談て、あるが , この原稿は , PC ー 9801 ノー ければいけない char t は , < stddef. h> の中て、 typedef によっ て定義される処理系定義の型て、ある。 トの MS ー DOS 上て、動作するフリーソフト ng 幸い , アルファベットや数字 , 記号の類も すべて 2 バイトコードの文字にしていたの 基本文字集合の要素て、ある 1 バイト文字も ( 日本語 Micro Gnu Emacs) を使って書いて いる。筆者は , 通常 , DOS 上て、も他システム て、 , そう複雑な処理にしなくても済んだが , 含めて , 拡張文字集合の要素は , 均一な大き List 修復用のプログラム List 1 for(i=l;i く max ; i + + ) { int 1 ; char * cp, *strrchr() ; cp = strrchr(buff[i-l], *cp = buffCi]C3); ' yxlb' ・ ' \ X28 ' ・ }x4a' ・ for(j=3;(c=buffCi]Cj + 1]) buffCi)Cj] = 00 4 ・ L.D ^ 0 叮ー 8 0 1 人りな 00 -4 ・一 -0 ^ しー 8 0 イ 1 ワ 0 っ 0 一 4- ^ 0 つんワ 0 りんつりつなワ CO 《 0 00 00 00 の 0 00 っ 0 れ 0 ・ 4- 4 ・・、 4- -4 ・ 4 4 ・ 1 : #include く stdio. h 〉 2 : #include く string. h> 3 : 4 : static char buff [ 500 ] [ 200 ] ; 5 : 6 : main() { int i,J; 7 : 8 : int max ; 9 : int c; 10 : 11 : for(j=0; (c=getchar()) ! = EOF ; j + 十 ) 12 : buffCi]Cj] = 13 : 14 : buffCi]Cj) = 15 : 16 : 17 : 18 : if(c==EOF) break; 20 : 22 : ' yxlb' ) ; for(j=3;(c=buffC0]Cj + (]) い ' 町 buffC0] CjJ ー for(i=0; i く max ; i + + ) { puts(buff[i]) ; break; max 42 C MAGAZINE 1 的 2 6

4. 月刊 C MAGAZINE 1992年6月号

C 概観 いか明確になっていない このように , 現在の the Standard C て、の多 バイト文字処理 ( 日本語処理はその特殊な場 合 ) を行うには , まだまだ間題点が山積して 現在 , ISO C の作業部会 WG14 て、は , the S tandard C に対する「補遺」 (Normatinve Ad dendum) を作成している。この Addendum は , 次にあげる三つのパートに分かれてい ・現仕様の更なる明確化 ( イギリスの提案 ) ・ 3 文字表記法の改善案 ( デンマークの提案 ) ・多バイト文字処理機能拡張提案 ( 日本の提 各提案の詳細な説明は省略するが , この A ddendum は順調に行けば 1993 年中には ISO レ ベルて、正式に登録される予定て、ある。また , この Addendum は , X3J11 て、も正式な提案と して検討されることが合意されており , WG 14 と X3J11 との合同国際会議て、検討されてい る。なお , 多バイト文字処理機能拡張仕様案 ( MuItibyte Support Extensi ons, 略して M SE という ) は , 日本の SC22 / CWG がテクニ カルエデイタになっている ( 本特集 PART 1 参照 ) 。 歴史をひもとけば , ワイド文字の概念の導 入は , 1984 年に発足した日本語 UNIX 諮問委 員会て、の検討にまて、遡ることがて、きる。日本 語 UN Ⅸ諮問委員会は , 当時の AT & T ュニッ クスパシフィック社の諮問を受け , 日本語を 扱える機能を取り込んだ UNIX の検討を目的 として , 東京大学の石田晴久氏を委員長と し , メーカーなどが参加して発足した委員会 Normative AddéR um ノト文字処理機能 拡張提案 ( MSE) 以下に , この MSE を簡単に紹介しよう。 MSE 作成の背景 て、ある。これ以降 , C 言語における多バイト 文字機能をはじめ , UN Ⅸの国際化機能は , この委員会の答申が基盤になっている。この 委員会発足以降 , Fig. 9 に示すようなプロジ ェクト , 委員会が発足し , 国際化機能を議論 し始めた。 このように , さまざまな団体て、似て非なる 仕様が作成されていったが , 国内て、も確固た る実績を持ち , デファクトスタンダードとな るに足る仕様は出現しなかった。 Fig. 9 のい くつかの委員会から , X3J11 に , 多バイト文 字を扱うライプラリ群の提案が何回か行われ たが , 当初は , 実績がない , という理由て、あ まり積極的に検討してもらうことがて、きなか った。 ANSI C の仕様自体が , ' 87 年頃には すて、に固まってきており , 前記のワイド文 字 , および mb 系基本 5 関数を追加することが 精一杯て、あった , というのが実情のようて、あ る。 その後 , 国内外て、乱立している多バイト文 字処理ライプラリを統合し , より完全な形 て、 , ISOC/ANSIC に提案を行うべく , 198 9 年 , 情処学会 SC22 / C WG の下に , 多バイト 文字処理検討サプワーキンググループが設け られた。このサプ WG て、は , 可能なかぎり , 各種関連団体から関係者に参加してもらい , 当時 , 世の中に発表されていた仕様 , あるい は検討中の仕様を網羅し詳細な検討を加え , 全体的にコナセンサスが取れた共通仕様を抽 出した。 1990 年 1 月 , このサプ WG て、作成された多 バイト文字処理提案は , ISO SC22/WG14 に 正式に提出され , ISO C の Addendum 案の一 部として議論されるよになった。 また , 現在て、は , X / Open をはじめ各標準 化関連団体は , 多バイト文字処理ライプラリ に関しては , この ISO SC22 / WG14 の仕様を 採用しており , WG14 の作業と同期を取り , 協力しあいながら仕様案の検討を行ってい る。さらに , ANSI の C 十十委員会 ( X3J16 ) て、も , この多バイト文字処理ライプラリを C 十十における I/O ストリームライプラリとし て取り込むことを検討している。 MSE の内容 特集第 3 の標準』 S C 概観 45 格厳密合致プログラム」て、 , すて、に , MSE の になっているのて、ある。すなわち , 現状の「規 ューザが使用可能な名前空間を侵さないよう じ込められている。 こうすることによって , ァイル < wchar. h > の中に関数原型宣言が閉 MSE のライプラリ群は , ひとつのヘッダフ MSE て、は未解決て、ある。 ストリーム , 複数文字集合の問題も現段階の すべてクリアされているわけて、はない。複数 the Standard C て、の日本語処理上の問題点が しかし , 残念ながら , 前述したさまざまな ード系に対しても十分な考慮が払われてい る。とくに , シフト状態に依存するようなコ 能なように検討が加えられ仕様作成されてい どのような文字コード体系て、あっても実装可 さらに , MSE のライプラリ群は , 処理系が るようになっている。 置き換えるだけて、 , 多バイト文字処理カイき 対して , 原則的には , 単純にライプラリ名を ト文字べースのテキスト処理のプログラムに を形成している。したがって , 従来の 1 バイ ヾイト文字べースのライプラリとのアナロジ また , これらのライプラリ群は , 既存の 1 な規定を設けることだけが許されている。 efined behavior) となってしまう部分に新た um て、は , 現仕様の中て、「未定義の動作」 (und いい換えれば , Addend なければならない 密合致プログラム」がそのまま受け付けられ 仕様を実装した処理系て、も , 既存の「規格厳 ることは許されない。つまり , Addendum の 仕様」て、あるから , 既存の仕様に変更を加え ただし , Addendum は , あくまて、も「追加 の機能をサポートするのて、ある。 が等しいワイド文字に変換して処理するため イト文字のままて、はなく , 各文字のバイト数 これは , あくまて、も , 文字列データを多バ 加する。 て、処理を行うための完全なライプラリ群を追 に修正を加えることなく , ワイド文字べース MSE て、は , 現状の the Standard C の仕様

5. 月刊 C MAGAZINE 1992年6月号

として解釈することが義務づけられている。 これは , たとえ漢字コードの中に , 変換指定 子を表わす 1 バイトの、、 % クと同じコードか凸 まれていたとしても , 処理系は , そのコードを 2 バイトの漢字コードの中のものて、あると認 識し , 誤動作することはないことを保障して いる。そこまて、は , いいとしよう。 問題は , % s 変換における「フィールド幅」 と「精度」て、ある。これは , 現規格て、は , バイ ト単位て、しか指定て、きない。しかもそれは , 処理データのメモリ中のバイト数て、あって , 画面やプリンタへの出力結果における印字幅 や出力幅単位て、はないのて、ある。これは , プ ログラマが , 各文字が処理データとしてメモ リ中て、何バイトを占めるか , あるいは , それ らが印字された場合 , どれくらいの幅を占め るか , ということをよく知っていなければな らないことを意味している。 さらに こて、もまた , シフトコードが混 入している場合 , 問題は , より複雑になる。 データのどこにシフトコードが入っている か , ということを一般のプログラマは関知し ていないからて、ある。しかし , そのシフトコ ードのバイト数も意識して「フィールド幅」や 「精度」を指定しなくていけないのて、ある。そ のようにあらわに文字のバイト数や出力幅を 意識してコーディングしてあるプログラムを 無修正て、別のコード系を採用している処理系 に持っていき正常動作させることはて、きな また , printf ( ) の出力結果のなかにも予期 Fig. 9 日本語化に関するプロジェクト , 委員会 せざるシフトコードが混入するて、あろう。 s printf() て、は , どれくらいの長さの出力バッ フアを用意したらよいのか予測しがたい scanf ( ) の問題 複数文字集合の問題 複数ストリーム る文字列の「シフト状態」 (shift state) を保持 mbtowc( ) , wctomb( ) は , 現在処理してい しておかなくてはいけない状況に似ている。 が現在処理している文字列のポインタを保持 処理て、きない。それは , ちょうど , strtok ( ) は , 残念ながら , 一度にひとつの文字列しか wc ( ) および wctomb ( ) の変換ライプラリ the Standard C て、新しく導入された mbto いて、あろう。 える。使いものにならないと思ったほうがよ 動作は , 一般に何が起きるかわからないとい 多バイト文字列に anf ( ) を適用した場合の 点があるが , 詳細な考察は省略する。要は , るからて、ある。これ以外にもさまざまな問題 い位置にシフトコードが混入してしまってい 式文字列のなかには , プログラマが関知しな 雑にする。プログラマがコーディングした書 こて、もまたシフトコードがものごとを複 チングて、ある。 ータとしての文字列の「バイト単位」て、のマッ ログラマが指定した書式文字列と , 実行時デ も深刻て、ある。 scanf( ) の動作の基本は , プ scnaf( ) の間題は , さらに , printf( ) より しておかなくてはいけないからて、ある。 , こて、いう「シフト状態」とは , たとえば , ある位置のバイトデータが 1 バイト文字に対 応するものて、あるのか , あるいは , 2 バイト 文字の一部をなすものて、あるのか , というこ とを示すものて、ある。ふたつの文字列を同時 に ( 交互に ) mbt 。 wc ( ) て、処理しようとする と , 一方の文字列のシフト状態て、別の文字列 を処理してしまうことになる。これは実用上 かなりきつい制限てある。 さらに , 前述したように , theStandardC て、扱う「拡張文字集合」の要素 ( 文字の種類 ) は , locale に依存して切り換えることが可能 て、ある。たとえば , 今は「日本の漢字」 , 次 は , 「韓国のハングル」といったように 0 、、 し , それは , setlocale( ) 関数て、行うのて、ある が , 現状て、は , どのようにして切り換える というところまて、は規定されていない また , 残念ながら , 現在の theStandardC の枠組みの中て、は , このような独立している 複数の文字集合を並列的に処理することはて、 きないと思われる。やるとしたら , 今話題沸 騰の「 ISO 10646 」 ( のように , さまざまな文 字をひとつの文字集合に統合したようなコー ド体系を用いるしかないて、あろう。 また , 同じ文字集合て、もそのエンコーディ ング規則の切り換えに関して , theStandar d C は , 何もいっていないように思われる。 たとえば , JIS, シフト JIS, EUC といったコ ード系の切り換え , あるいは , それらの複数 コード系の並列処理をいったいどうしたらよ 日本語 UN Ⅸ諮問委員会 ( 1984 年に発足 ) プロジェクト ( 1985 年に発足 ) 旧 0 SC22 / WG14 ( 1986 年に発足 ) 情処学会 SC22 / C WG ( 1986 年に発足 ) X3JI 1 国際機能 Ad hoc 委員会 ( 1986 年に開催 ) ソフトウェアベンダーを中心とした日本 C 言語委員 ( 1987 年に発足 ) X/Open UN Ⅸインターナショナル OSF JUS など 44 C MAGAZINE 1 的 2 6 Fig. 10 命名規則 ISXXX - → ISWXXX toxxx ー ' towxxx f{getl put} { い引 char} f{get :put} w{cl 曲 a 「 } [ 日 s] {printfl scanf} [ 日 s] w{printf lscanf} ー , WCS Str

6. 月刊 C MAGAZINE 1992年6月号

PART C プログラム標準合致度検査 コンノヾイラか AN 日規格や旧 0 規格に合致しているかどうかを検査するには , Plum H all Validation Suite をはじめとする各種テストスイートが存在する。しかしこれ らテストスイートはあくまでコンノヾイラの規格合致度を検査するものであり , プログラ ムか ANSI 規格 , 旧 0 規格に合致しているかどうかを検査するもので一よい。 ANS い S 0 , そして』 S C と , C 言語規格カーされていく現在 , 廠密に規格に合致した C プログ ラムこそか重要となる。本ノヾートでは英国 Know dge SO 仗 wa 「 e 社か開発した C プログラム標準合致度テストスイート・ Modellmplementation fo 「 C を中心に C 言語の標準合致度検査について考えていく。 ANSI て、の C 標準化は ' 83 年に作業が開始さ れ , ' 89 年 12 月に正式な規格となった。さらに ' 90 年 12 月には ISO 規格が出版された。このふ たつの規格はセクション番号など文書形式上 には違いはあるが , 技術的内容は同じて、あ る。そのため本稿て、はおもに ISO という名称 を使用するが , 多くの場合 ANSI と置き換え ても問題はない これらの標準化作業の多くは米国て、行わ れ , かなり早い段階から多くの米国内のコン パイラベンダや一部大手 C ューザの注目を集 めていた。また日本やヨーロッパのコンパイ ラベンダなどからの注目も , 作業の後半には 高まった。このような世界的な注目のなかて、 標準化作業が行われたわけて、あるが , ら派生してきた要望が「コンパイラの標準規 格合致度の検査」て、ある。この要望はとくに コンパイラベンダからのものが強く , それに 応えるために開発されたものが PIum HaII V alidation Suite をはじめとする各種テストス ィートて、ある。 余談になるが , テストスイートという単語 に聞き覚えのない読者のために若干の説明を C 標準とテススート しておこう。テストスイートは test suite をそ のままカタカナにしたものて、ある。日本語て、 ホテルのスイートルームというときの「スイ ート」がこの suite に相当し , 一組みとか一続 きを意味する ( もっとも , 英語て、は suite だけて、 もいわゆるスイートルームを表すようだが ) 。 C コンパイラの検査プログラムの場合 , 複数 の ( 通常は多くの小さな ) テストプログラム を使うのて、 , これらの複数のテストプログ ラムー式をテストスイートと呼ぶ。これは 他言語用のコンパイラ検査て、も同様かもし れない 現在入手可能な C コンパイラ用のテストス ィートのなかにはネットワークなどから入 手て、きるフリーソフトウェアも含まれてい る。しかし実際に検査に利用してみると , フリーソフトウェアには限界があることが 簡単にわかってしまう。そのため現在て、も この種のフリーソフトウェアを使用してい るのは , 一部の一般ューザと比較記事など を掲載している雑誌社程度て、ある。 現状て、は , ほとんどのコンパイラベンダ は何らかの商用テストスイートを使用して いる。また , ョーロッパて、はすて、に英国の BSI (British Standard lnstitute) を中心と した公的な機関により C コンパイラの検査が 行われている。米国て、も NIST(National ln C 概観 福富寛 特集第 3 の標準』 s c 概観 47 ②すべての処理系に対して , 完全に同じ検 のバグも発見しやすくなる。 により , コンパイラとランタイムシステム こうすること し検査するほうが望ましい て、はなく , 何度もパターンを変えて繰り返 らに , これらの要求を一度だけ検査するの 全に区別し , 検査しなければならない。さ 動作て、ある。テストスイートはこれらを完 三つめは規格て、処理系定義とされている しなければならない ラーメッセージなり診断メッセージを出力 動作て、ある。この場合処理系はきちんと工 どの制限とされているような入力に対する ふたつめは規格て、シンタックスエラーな た入力に対する動作て、ある。 ひとつは正常な , すなわち規格に合致し それも 3 種類に分類することがて、きる。 当然ながら処理系に対するものて、あるが , するものがある。 こて、いう要求事項は , の処理系に対するものと C ソースコードに対 ISO 規格の要求事項には , コンパイラなど と ①旧 0 規格での要求事項をすべて検査するこ 必要とされる特性をここて、考えてみると , ところて、 , こういったテストスイートに テストスイートの、須条件 いは使用される予定て、ある。 のテストスイートが使用されている , ある の公的な機関による検査て、も , すべて商用 検査を開始することになっている。これら 検査検定協会 (略称は JMI) が 7 月から同様な 月から , さらには日本て、も , ( 財 ) 機械電子 stitute 0f Standards and Techn010gy) が 4 株アドバンスド・データ・コントロールズ ) (lTSCJ/SC22/C WG,ISO W 引 4 メン / ヾ

7. 月刊 C MAGAZINE 1992年6月号

三 JIS C 概観 TabIe 2 the Standard C で新しく導入されたマッピングのための関数 関数 int mblen(const char * , size t) int mbtowc(wchar t * , const cha 「 * , size t) int wctomb(char * , wcha 「 t) size t mbstowcs(wchar t * , const char * , size t) size t wcstombs(char * , const wchar t * , size t) , 多バイト文字 1 文字分のバイト数を返す 内容 ワイド文字列を多バイト文字列に一括変換する 多バイト文字列をワイド文字列に一括変換する ワイド文字 1 文字を多八イト文字 1 文字に変換する 多バイト文字 1 文字をワイド文字 1 文字に変換する さのワイド文字にマッヒ。ングされる。マッヒ。 ングは , theStandardC て、新しく導入された Table 2 に示す関数によって行われる。これ らの関数名て、 , 、、 mb 〃は , 多バイト文字 ( mu ltibyte character) を表し , 、、 wc クは , ワイ ド文字 (wide character) を表している。 言語仕様面て、も , Fig. 6 のような記述が このようなライプラリが追加されたと同時 ワイド文字列定数 例 ) L' 字 ,, L'a' ワイド文字定数 Fig. 6 言語仕様面可能になった記述 これらの新しい機能を用いたテキスト処理 7 に示しておく。 列とワイド文字列とのマッヒ。ングの例を Fig. ed short) て、 typedef した場合の多バイト文字 wcahr t を 2 バイトの型 ( たとえば , unsign 可能となった。 の概念は , Fig. 8 のようになる。 Fig. 8 て、示す , 「ワイド文字列の加工」の部 分は , 「 1 文字 = = 1 バイト」て、ある ASCII の 世界て、のテキスト処理と同じロジックがその まま適用て、きる。ワイド文字単位て、処理を行 うなら , もはや , プログラム中て、 , シフトシ ーケンスを生に意識したり , 2 バイトコード の片割れを意識したりする必要性はないのて、 ある。 ただし , 先ほどの筆者の文字化け修復プロ グラムて、は , 元々不正な文字コードの入力を 仮定している特殊な場合て、あるため , このよ うなワイド文字べースのプログラムに置き換 えるわけにはいかない 現規格での問題点 数て指定される書式文字列を多バイト文字列 現規格て、は , 処理系は , printf( ) の第一引 p 「 intf( ) の問題 て、ある。 まず , 間題になるのが , printf(), scanf() て、ある。 的なプログラムを記述するにはまだまだ不足 が導入されてはいるが , これだけて、は , 実用 ardC て、は , 多バイト文字処理のための機構 以上 , 簡単に説明したように , theStand 例 ) L"this is ワイド文字列 " wchar t 型配列の初期化 例 ) #include く stddef. h> wchar t buff [ ] L"this is 漢字 " Fig. 7 多バイト文字列とワイド文字列とのマッピングの例 多バイト文字列 "a 日 x" 'a' シフトイン シフトアウト 0X61 OXIB 0X24 0X42 0X46 0X7C OXIB 0X28 0X4A 0X78 0X00 mbstowcs( ) ↓ wcstombs( ) ↑ L' 日 ' L L'YO' 0X00 0X61 0XA4 0XC2 0X00 0X78 0X00 0X00 ワイド文字列 L ” a 日 x ” Fig. 8 新しい機能を用いたテキスト処理の概念 漢字を含むテキストファイ丿い getchar( ) , getc( ) , fgtec( ) 入力 gets( ) , fgets( ) メモリ char buffC ] ; 変換 mbtowc( ) , mbstowcs( ) # include く stddef. h 〉 メモリ wchar—t buffC ] ; wchar—t*wp = &buffCO] ; ワイド文字列の加工 変換 wctomb( ) , wcstomb( ) メモリ char buffC ] ; putchar( ) , putc( ) , fputc( ) 出力 puts( ) , fputs( ) 漢字を含むテキストファイ朋 特集第 3 の標準』 S C 概観 43

8. 月刊 C MAGAZINE 1992年6月号

アルゴリスム テータ構造入門 近藤嘉雪 く第 18 回〉キャッシュ 今回はキャッシュという技法についてお話しまし よう。これは今までとは少し傾向か違い ( 表現か適 切でないかもしれませんか ) 泥くさい話題です。し かし , これは , ハードウェアの面でも , ソフトウェア の面ても非常に大切な概念です。 ます。 ードウェアの分野て、は , とくにメ キャッシュと ( ま 60 C MAGAZINE 1992 6 ソフトウェアの両方の分野て、利用されてい キャッシュという技法は , ハードウェア , キャッシュメモリ と時間のトレードオフの問題になります。 するべきかどうかは , 以前にお話した空間 領域が必要になるのて、 , キャッシュを採用 結果をとっておくためには , そのための といった意味があります。 どをたくわえ , または隠しておく地中の穴 ) 』 『貯蔵所 , 隠し場所 ( 探検者が食料・弾薬な ache) といいます。 cache という言葉には , を保存しておくための機構をキャッシュ (c ッシング (caching) といいます。また , 結果 処理の高速化を図る」という技法全般をキャ て , それを後ほど再利用することによって このように , 「処理の結果を保存しておい て、きるようになります。 を避けられ , より高速にプログラムを実行 っておけば , 同じ処理を繰り返し行うこと ます。このような場合 , 結果をどこかにと 行った結果が , 再び必要になることがあり プログラムを書いていると , ある処理を モリの読み書きを高速化するために , キャ ッシュが利用されます。 ノヾーソナルコンヒ。ュータやワークステー ションて、使われているマイクロプロセッサ ( 以下 , CPU といいます ) は , 急激に高性能 化しています。性能の向上は , CPU 自体の 高性能化 ( ビット長の増加 , 命令セットの改 良 , 内部処理の高速化 ) と動作周波数の高速 化によって達成されてきました。 パーソナルコンヒ。ュータを例にとってみ ま・しよう。 8 ビットの時代にはせいぜい 5 ~ 8 MHz くらいが一般的て、したが , 最近て、は 20 MHz とか 33MHz というマシンが普通になり つつあります。 このように CPU の動作が高速になると , それに見合うだけアクセスが高速 ( データの 読み書き時間が短い ) なメモリを用意しなけ ればなりません。もし , CPU の速度に比べ て , メモリのアクセス時間が遅すぎると , メモリがボ、トルネックになってしまって , システム全体の性能が頭打ちになってしま います。 しかし , メモリはアクセスが高速なもの ほど高価なのて、 , CPU の速度に見あったメ モリのみを使うと , 極めて高価になってし まいます ( もちろん , コストを度外視して も , 高性能なマシンが必要な分野もありま ↓ モリに入れておくという方法をとります。 参照される部分だけをアクセスの高速なメ にはアクセスの遅いメモリを使い , 頻繁に こて、 , ①と②の折衷案として , 基本的 す。 いシステムを構成する必要が生じるわけて、 段の安い ) メモリを使って , 何とか性能が高 しなくなります。そこて、 , 比較的低速な ( 値 にせよコストパフォーマンスはあまり向上 のどちらかを選択することになり , いずれ る 性能は上がるが , 値段がとても高くな ↓ ムを構成する ②アクセスが速いメモリを使ってシステ てさほど性能が上がらない 値段は安いが , メモリがネックになっ ムを構成する ①アクセスが遅いメモリを使ってシステ 速になると , つまり , CPU の動作周波数がある程度高 す ) 。 も , コストパフォーマンスのほうが重要て、 ークステーションて、は , 絶対的な性能より す。しかし , パーソナルコンヒ。ュータやワ

9. 月刊 C MAGAZINE 1992年6月号

mcc て、はこのように細かい検査が行われる が , さらにこのチェッカて、はリンカ (mcl) と インタブリタ (mci) て、も検査を行う。実はこ れらが検査機能の大幅な向上に役立ってい るのて、ある。 リンカて、コンパイラの出力したファイル が結合されるのは当然だが , mcl はその結合 に加えて , すべてのファイルて、の ( 外部リン ケージを持っ ) 変数や関数の宣言・定義 , さ らにはマクロ定義の一貫性まて、検査する。 たとえば List 3 のそれぞれのファイルは ( プ ログラムとしては何の意味もないが ) 何の問 題もなくコンパイルて、きる。 Fig. 14 mcl が出力した警告メッセ 81 (Sun 4 Unix) version 2.0 i in fi le S short int and S 1 1 in file m int ・ ージ Copyr ight ところがコンパイル結果をリンクしてみ ると ,Fig. 14 のような警告が mcl から出力さ 宣言や定義が一致していない部分が指 れ , 摘される。これはプログラムの規格合致性 の検査だけて、なく , 有効性のチェックとし ても有益て、あろう。図中のメッセージて、は マクロ定義の不一致も指摘されているが , もちろんこれは規格違反て、はない。しかし , より安全なコーディングのためにはマクロ 定義を統一しておくことが望まれる。その ため , この mcl て、のマクロ定義検査は起動時 のコマンドラインなどて、必要に応じて ON/ OFF て、きるようになっている。 (c) 1990 ー 91 0 響 1 ge Software Ltd C 概観 に合致したプログラム」て、あることが確信て、 だけの検査をパスさせることて、「厳密に規格 ラや lint て、は実現て、きない機能て、ある。これ ッカの大きな特徴て、あり , ほかのコンパイ このように 3 段階におよぶ検査がこのチェ が発見て、きる。 項目や「未定義」項目に動的に依存する動作 警告が出力される。これにより「処理系定義」 ンタブリタて、実行させると , Fig. 15 という 初期値 100 を設定するように変更し , このイ g. 12 のプログラムを , j に初期値 400 , i には する場合を検出するのて、ある。ちなみに Fi に「処理系定義」動作が条件的 ( 動的 ) に発生 チェックされ , Fig. 12 のプログラムのよう この mci て、はプログラムの実行時の動作が いるため , インタブリタと呼ばれている。 と同様に元のソースと 1 対 1 の対応になって が , mcl からの出力も前述の mcc からの出力 ものて、ある。シミュレータのようて、もある 入力を読み込み , それを仮想的に実行する そして最後は mci て、あるが , これは mcl の Warning: lncompatible types between definition and declaration foo(new-style) in file s function (int (k) returning short int ・ and Symb01 foo(old-style) in file m function ( ) returning int ・ Warning: lncomlhtible tyrES between definition and declaration Fig. 15 mci が出力した警告メッセージ #define STCONS 50 and #def i ne STCONS 40 Warning: Macro differ between files Warning: lncomlhtible between call and its definition. Warning: Function ßnrameters are lncompatible function ( ) returning int ( 511 from m) function (int (k) returning short int ・ foo(old-style) in file s Warning: lncomßhtible return mci (Sun 4 Unix) version 2.1 Copyright (c) 1990 ー 91 0W1 ge S0ftware Ltd C MAGAZINE 1992 6 warning: shift by value larger than bits in left operand is undefined warning: out Of range signed value cast tO signed is i 叩 leIIEntation defined きるのて、ある。逆に こまて、の検査をパ スしなければ「厳密に規格に合致したプログ ラム」だと断言することがて、きないのて、あ ただし , これらのどの段階て、も検査対象 になっていない「処理系定義」項目がいくっ かある。それらには , 各データ型のサイズ , ビットフィールドの割り付け順 , int 型ビッ トフィールドて、の符号の扱い , 負数の算術 右シフト時の符号ビットの扱いなどがあり , おもにターゲット CPU に依存する項目てあ る。これらはコンパイル時にコンフィグレ ーションファイルまたはコマンドラインか ら指定て、きるようになっているため , 広範 囲なターゲット CPU を仮定しコンパイルて、 きる。そうして得られた各種ファイルをイ ンタブリタて実行し , 結果を比較してみれ ば , そのプログラムが上のような「処理系定 義」項目に依存しているかどうかが判明す る。つまりこの C モデルインプリメンテーシ ョンは厳密さと柔軟性を合わせ持っチェッ 力といえよう。 52

10. 月刊 C MAGAZINE 1992年6月号

査を行うこと。つまり , テストスイート 自体は「厳密に規格に合致したプログラム」 でなければならない これはテストスイート作成には細心の注 意が必要なことを意味する。つまり , ターゲ ット CPU や動作環境に依存する部分をスイ ートから排除しなければならない。このよ うな部分には , int 型やポインタ型における サイズの違い , 2 の補数演算か 1 の補数演算 かの違い , 文字コードとして ASCII を使うか EBCDIC を使うかの違い , レコードベースの 入出力かストリームペースの入出力かの違 いなどがある。 ③テストスイート自体にはバグがないこと これは当然のことて、あるが , 実現は簡単 て、はない。最終的には多くの処理系を検査 し , その結果からバグを発見し修正するし か方法がないだろう。とすれば実績の多い スイートほど有利だといえよう。 ④テストプログラムすべてのコンパイル / リ ンク / 実行や検査結果の収集を行うための 手段 , つまりツールが提供されること これもスイートのユーザとしては当然の ことて、あろう。しかし多くの環境て、同じよ うに動作する , つまり異なるオペレーティ ングシステムと異なる処理系に対して同じ ように動作するツールを提供することは , それほど簡単て、はない。これも実績により 改良されていく性格を持っている。 ⑤標準を満たすことを検査するプロセスが 明確にドキュメント化されていること これはスイート提供者にとっては一種の 企業秘密をドキュメント化することになる。 しかしこのドキュメントによりスイート提 供者の規格に対する解釈が理解て、きる。も ちろん , コンパイラ製作者自身もそのよう な解釈を持っている。あまり頻繁てはない が , この二者の解釈が異なる場合て、も , のドキュメントがあれば無用のバグレポー トや議論を避けられるだろう。 現在公的な機関に受け入れられているテ ストスイートは , もちろんこれらの条件を ほとんど満たしている。ただひとつの問題 48 C MAGAZINE 1992 6 は , 機関間の相互認定て、ある。これは , た とえば , 日本て、の検査結果をそのまま米国 やヨーロッパの機関に受け入れてもらった り , 欧米て、の検査結果をそのまま日本て、受 け入れることを指す。 日米欧の状況 C の検査に関してはヨーロッパが先行し , それに日米が続いたわけて、あるが , その際 に三者が完全に独自に計画を進めてきたの て、はなかった。ヨーロッパの BSI は各種スイ ートを独自に検討し PIum HaII Validation Suite の採用を決めたのだが , その当時は日 米も BSI と同じスイートて検査を行うことを ( おそらく非公式に ) 約束していた。 しかしその後の政治的な状況の変化て、 NI ST は BSI とは異なるスイートの採用を決定 し , 一方の JMI は BSI と同じ PIum HalI Va lidation Suite の採用を決定した。これて、相 互認定に関するかぎり日欧 vs 米という図式 になった。それて、も日米欧の 3 機関によるミ ーティングは定期的に行われており , そこ て、相互認定に関する議論も行われている。 このミーティングの成果に期待したいのだ が , 政治的な思惑もからんているようなの て、成果の予想が難しい このようにまだ政治的な問題は残るもの の , C コンパイラの標準規格合致度検査は一 般的になってきており , 技術的にも安定し ている。現在のところ規格に完全に合致し たコンパイラを見つけることは容易て、ない が , 検査の一般化が C ユーザにもたらすメリ Fig. 12 「処理系定義」などの例 char c; signed int i, J, k; ットとして , 各種 C コンパイラて、の言語仕様 を ISO 規格レベルて、統一させる , あるいは安 定させることが期待て、きるて、あろう。少なく とも各種 C コンパイラの言語仕様の違いを I SO 規格をベースに比較て、きるようにはなる だろう。 もちろん , なかには「 ANSIC て、の新機能 をサポート」とか「 ANSIC 準拠」とだけ表明 し , 合致内容などを明確にしないべンダも ' ういったべンダからの 存在するだろう。 コンパイラには ISO 規格べースの言語仕様を 期待て、きないし , してもいけない このようなコンパイラを使ってはいけない といっているのて、はない ( 個人的には淘汰さ れると思っているが ) 。というのも , 最終的 にコンパイラを選択するのはユーザて、あり , その選択基準は各ューザ独自のものて、ある からだ。 ポータビリティのため ISO 仕様を重視する か , それともターゲット CPU に有利な特殊 機能を重視するか , あるいは使いやすさを 重視するか , など選択の幅は広い 規格化のメリッ それて、は , C コンパイラの言語仕様が ISO 規格べースになることのメリットについて , もう少し考えてみよう。規格制定以前には , ほとんどの商用コンパイラが「 K & R 準拠」だ ったが , 各コンパイラて、の実際の仕様はか なり異なっていた。そのためどのコンパイ ラて、もコンパイルて、きるポータブルなプロ グラム作成が非常に困難だったことを記憶 この代入の結果は j の値が signed char 型て表現てきないとき (signed char 型の値の範囲を越えるとき ) 「処理系定義」てある この左シフトの結果は j の値が i のビットサイズ以上のとき 「未定義」である