addq - みる会図書館


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

1. 月刊 C MAGAZINE 1992年1月号

List 8 ないて、しよう。 int block prof exit ( ) を呼び出す前か , main() を終 わる直前に 0 にすればプロファイラ情報を 出力しません。 FILE *_block prof file プロファイラ結果を書き出す FILE 構造 体へのポインタて、す。 NULL( 初期値 ) の 場合は stdout に出力します。 void display_profile (void) 明示的に呼び出せばその時点てのプロ ファイル情報を出力します。 終わりに 冒頭から「バグレポート」の羅列て、 , 「 X68 000 版 GCC ってバグがたくさんあるんだ・・・ と思われた方もいらっしやるて、しよう。て、 も , 68881 関係のバグ以外は私が移植改造し た GCC にかなり長い期間潜んて、いて発見さ れたバグなのて、す。バグフリーて、あるわけ はなくとくに私が移植した GCC は CPU パワ ーが低い 68000 て、 1 クロックて、も削るように また少して、も便利なようにオリジナル GCC から大幅に変更を加えてあります。 GCC が Ver. 1.40 になった時点からバージ ョン表示て X6 ? ? (Based on 1.40 ) と表示す るようになったのは , かなりオリジナル GC C から逸脱したコード生成をするようになっ たためて、す。 現在 , GCC はおもにパソコン通信て、サポ ートしていますがこの℃マガジン』て、だけ しかサポートを受けられない読者の方々も , 何かの不具合 , 疑問要望などがありました らご連絡ください。サポートを保証するわ けてはありませんが , この GCC は熱心な X6 8000 ューザからの多くバグ報告 , 要望て現 在の形になった亜流 GCC てす。また現在 , SX-Window 専用の GCC, assembler, link er が開発されつつあります。 これらは , SX ー Window の C アプリケーシ ョンを開発するためにとくにリエントラン bne ? 63 34 addq. 1 # 1 , ? PBX2 + 20 36 c 叩 . b # 4 , 2 ( a の bne ? 63 38 addq. 1 # 1 , ? PBX2 + 24 move. b 3 ( a の , dl 41 ls 「 . b # 4 , dl 42 moveq. 1 # 0 , d0 43 44 move. b d1,d0 btst # 0 , d0 bne ? 63 addq. 1 # 1 , ? PBX2 + 28 move. 1 12 ( a5 ) , a3 move. 1 a0, a4 50 mo 冊 . 1 4 ( al ) , d4 51 c 叩調 # 0 , a3 52 beq ? 63 53 addq. 1 # 1 , ? PBX2 + 32 55 moveq. 1 # 0 , d3 56 addq. 1 # 1 , ? PBX2 + 36 59 move. 響 (a3),d0 60 c 叩 . 響 # 15 , d0 ? 63 62 addq. 1 # 1 , ? PBX2 + 40 64 c 叩 . 響 # 14 , d0 65 addq. 1 # 1 , ? PBX2 + 44 68 c 叩 . 青 # 17 , dO 69 . b ? 63 addq. 1 # 1 , ?PBX2 + c 叩 . 響 # 13 , dO bne ? 70 addq. 1 # 1 , ? PBX2 + 52 mo 冊 . 1 16 ( a3 ) , aO move.w (a の ,d0 c 叩 . 響 # 20 , d0 80 beq ? 63 addq. 1 # 1 , ? PBX2 + 56 82 cmp. 響 # 22 , dO 83 addq. 1 # 1 , ? PBX2 + 60 c 叩 . 響 # 13 , ( ) 88 89 bne ? 72 addq. 1 # 1 , ? PBX2 + 64 mo 冊 . 1 16 ( a3 ) , a0 92 。叩 . 響 # 25 , (a の、 93 94 bne ? 72 addq. 1 # 1 , ? PBX2 + 68 move. 1 4 ( a の , -(sp) mo 冊 . 1 a4,-(sp) 99 Jsr —reg_mentioned_p addq. 響 # 8 , sp 100 tst. 1 d0 101 beq ? 72 102 addq. 1 # 1 , ? PBX2 + 72 104 nove. 1 16 ( a3 ) , a0 105 田 ove. 1 4 ( a の , al 106 c 叩 . 響 # 34 , (al) 107 108 bne ? 63 addq. 1 # 1 , ? PBX2 + 76 110 田 ove. 1 4 ( a4 ) , d2 111 c 叩 . 1 4 ( al ) , d2 112 113 bne ? 63 115 addq. 1 # 1 , ? PBX2 + 80 X68k 活用講座 143

2. 月刊 C MAGAZINE 1992年1月号

Li st 8 トなプログラムを作成するための機能を備 えています。プロトバージョンはすて、にパ move. 1 8 ( a の , a0 116 : c 叩 . 響 # 30 , (a の 117 : ソコン通信て、入手可能になっていますのて、 , 118 : bne ? 63 119 : ?PB21: 興味のある方は参加されるのもいいと思い addq. 1 # 1 , ? PBX2 + 84 120 : c 叩 . 1 4 ( a の , d4 121 : ます。 122 : bne ? 63 123 : QPB22: 某ゲーム雑誌にて某 X68k 有名ソフトハウ addq. 1 # 1 , ? PBX2 + 88 124 : move. b 3 ( al ) , d0 125 : ス [ 注 4 ] の方が「 C て、は遅くて・・・・・・」とおっし lsr. b # 4 , d0 126 : 田 ove. b d0, d3 127 : やっておられますが , GCC て、は「下手なアセ btst # 0 , d3 128 : bne ? 63 129 : ンプラ」より速いことが多々あります [ 注 5 ] 130 : ?PB23: addq. 1 # 1 , ? PBX2 + 92 131 : move. 1 a3, -(sp) 大規模なソフトをアセンプラて、記述するの 132 : jsr —delete—insn 133 : addq. w # 4 , sp はアマチュアには手が出ないものて、す。複 134 : 135 : ? 72 : 136 : ?PB24: 雑なアルゴリズムもメンテを考えるとアセ addq. 1 # 1 , ? PBX2 + 96 137 : c 叩 . w # 13 , (a3) 138 : ンプラは躊躇します。一見アセンプラガリ 139 : bne ? 67 140 : ?PB25: ガリのようなゲームて、も大半は C だったりし addq. 1 # 1 , ? PBX2 + 100 141 : move. 1 16 ( a3 ) , al 142 : ます。要は「バカとハサミは使いよう」だと c 叩 . w # 25 , (al) 143 : 144 : bne ? 67 思います。 145 : ?PB26: addq. 1 # 1 , ? PBX2 + 104 146 : move. 1 8 ( al ) , a0 147 : c 叩調 # 30 , (a の 148 : [ 注 1 ] bne ? 67 149 : 150 : ?PB27: NIFTY-Surve FSHARP にアップロードさ addq. 1 # 1 , ? PBX2 + 108 151 : c 叩 . 1 4 ( a の , d4 152 : bne ? 67 れています。 153 : 154 : ?PB28: addq. 1 # 1 , ? PBX2 + 112 155 : [ 注 2 ] move. 1 4 ( al ) , a0 156 : c 叩 . # 37 , (a の 157 : 環境変数の、、まりこ〃は漢字の場合は「真里 bne ? 67 158 : 159 : ?PB29: 子」て、す。 10 月号 P172 の補足説明は間違っ addq. 1 # 1 , ? PBX2 + 116 160 : move. b 2 ( a0 ) , dl 161 : ています ( これは FEP が悪い。「まりこ」て、変 c 叩 . b # 3 , dl 162 bhi ? 67 163 換するとたいていは「真理子」になるからね addq. 1 # 1 , ? PBX2 + 120 165 え。ちなみにこの「真里子」は『少年サンデ 田 ove. 1 4 ( a4 ) , d0 166 moveq. 1 # 7 , d2 167 ー』のマンガにて、てくる女の子の「真里子」 c 叩 . 1 d0,d2 168 169 blt ? 67 て、はありません ( 誉 ; ) ) 。 addq. 1 # 1 , ? PBX2 + 124 171 [ 注 3 ] move. 1 d0, -(sp) 172 move. b dl, d3 173 GCC の作者 R. M. Stallman 氏は #pragma に move. 1 d3, -(sp) 174 peaW 34 175 関しては批判的て、す。が , この場合はよい 176 Jsr —gen—rtx move. 1 16 ( a3 ) , a0 177 方法がほかになさそうなのて、・・・ move. 1 d0, 8 ( a の 178 lea 12(sp), 179 [ 注 4 ] 蛇足て、すが , このメーカーさんの第 1 作には addq. 1 # 1 , ? PBX2 + 128 182 move. 1 12 ( a3 ) , a3 183 偶然動いていたという類のバグがあります。 c 叩 . 響 # 0 , a3 184 185 bne ? 78 [ 注 5 ] 187. ?PB33: addq. 1 # 1 , ? PBX2 + 132 188 : プログラム全体としてみれば , GCC も人間 move. 1 12 ( a5 ) , a5 189 : 190 : c 叩 . 響 # 0 , a5 には決して勝てないて、すが , 短いプロック 191 : bne ? 79 192 : ? 81 : て、の命令のクロック数て、はたいてい GCC が movem. 1 ( s の + , d3/d4/a3/a4/a5 193 : 194 : rtS 最小て、す。 meve. 1 # 2 , .. をいつばい並べた よりは・・・ 144 C MAGAZINE 1992 1

3. 月刊 C MAGAZINE 1992年1月号

List 7 詳細プロファイラ機能としてプロック単 位て、の実行回数を計測て、きます。コンパイ 22 : ル単位全体をプロック単位計測する場合は 23 : 24 : -a オプションを指定してコンパイルしてく 25 : 26 : ださい。プロック単位プロファイラてはラ 28 : イプラリは自動リンクしないのて、 , 明示し 30 : て proflib. a(. l) をリンクしてください 32 : TabIe 2 カⅨ 68000 版 GCC の独自最適化ル 33 : 34 : ーチンソースて、のプロックプロファイル結 35 : 36 : 果て、す。 List 7 がそのソース , List 8 が Lis 38 : t 7 をコンパイルしたアセンプラソースて、 39 : 40 : す。 if 文は条件ごとにプロック分割されてい 41 : 42 : 43 : これらの結果のように , 非常に細かな実 44 : 45 : 行単位て、実行回数を計測て、きますが , 大き 46 : なファイルて、これを行うのはかえって不便 48 : なだけなのて、 , # pragma て、プロック単位てプ 50 : ロファイルをする部分を指定て、きます [ 注 3 ] 。 52 : 53 : #pragma bl 。 ck て、「行う」「行わない」の条 54 : 55 : 件が反転します。たとえばヾー a 〃て、全体を 56 : プロファイル指定してあったら , 58 : #pragma block に出会った時点からプロ 59 : 60 : ファイルを行わなくなります。再度 #pragm a block に出会うとその時点から , プロファ イルを行います。、、一 a 〃が指定されていない と #pragma block に出会うとその時点から 1 . even ・・となるわけて、 プロファイルコンノヾイル・・ ”田 . 1 d3/d4/a3/a4/a5, ー (sp) 3 tst. 1 ?PBXO す。 #pragma block は必ず top level になけ 4 bne ?PI 2 5 6 pea ?PBXO ればなりません。関数内部を #pragma b10 bb_init_func 7 JSr addq. 響 # 4 , sp 8 ck て、分けることはて、きません。行った場合 はどんな動作をするかわかりません。 addq. 1 # 1 , ?PBX2 + 0 11 no 冊 . 1 24(sp),a5 12 プロファイル結果はソースのアセンプラ c 叩 . 響 # 0 , a5 13 レベルて、のコンノヾイルコードソースを作っ ておかないとほとんど意味がありませんし , addq. 1 # 1 , ?PBX2 + 4 0 叩 . 響 # 13 , (a5) 18 ソースとの対応などわからない人て、はまっ bne ? 63 19 たく無用の長物て、す。このプロファイラは addq. 1 # 1 , ? PBX2 + 8 move. 1 16 ( a5 ) , a0 22 少々知識が必要ということになります。 c 叩 . w # 25 , (a0) 23 24 bne ? 63 int prof size addq. 1 # 1 , ? PBX2 + 12 26 move. 1 8 ( a の , al 27 プロファイラを行うソース単位て、の最 c 叩 . 響 # 30 , (al) 28 29 bne ? 63 大数を指定します。プログラムて明示・ addq. 1 # 1 , ? PBX2 + 16 初期化すれば増やすことがてきますが , move. 1 4 ( a の , a0 32 c 叩 . 響 # 34 , (a0) 33 30 個確保しますのて , まず通常て、は問題 Ⅱ GET-CODE (st) = JUMP_INSN Ⅱ GET_CODE (st) = CODE_LABEL) break : if (GET_CODE (st) = INSN & & (GET_CODE (PATTERN (st)) = PARALLEL Ⅱ GET-CODE (PATTERN (st)) = = ASM-OPERANDS)) break ; if (GET_CODE (st) = INSN & & GET-CODE (PATTERN (st) ) = SET & & reg—mentioned—p (reg, SET—DEST (PATTERN (st)))) rtx dest = SET_DEST (PATTERN (st)) : if (GET_CODE (dest) = 三 REG & & REGNO (reg) = = REGNO (dest)) if (GET_CODE (SET_SRC (PATTERN (st))) = = CONST_INT & val ー = INTVAL (SET_SRC (PAffERN (st))) & & IREG_USERVAR_P (SET_DEST (PATTERN (st)))) delete—insn (st) : else break; else break; if (GET_CODE (st) = INSN & & GET_CODE (PATTERN (st)) = SET & & GET_CODE (SET_SRC (PATTERN (st))) = CONST_INT & & val INTVAL (SET_SRC (PATTERN (st))) & & GET_CODE (SET_DEST (PATTERN (st))) = MEM & & (int) GET—MODE (SET—DEST (PATTERN (st))) く (int) SImode & & REGNO (reg) く 8 ) SET_SRC (PATTERN (st)) = gen—rtx (REG, GET—MODE (SET—DEST (PATTERN (st))), REGNO (reg)) : LiSt 最適化ルーチンをコンパイルしたアセンプラソース 142 C M AGAZIN E 1992 1

4. 月刊 C MAGAZINE 1992年1月号

トが使えるように拡張してあったのて、すが , これがバグっていました。 List 2 の、、ソクの文字の 2 バイト目は、、 \ ク のコードて、あるために , 行継続と認識して 次の行の、、 f00 ( ) ; 〃が消失してしまいま す。なお , この、、 P クは gcc ccl. x の制御文 字と競合していましたのて、 , 、、十〃に変更さ れています。 MS-DOS などの一部のコンパイラてソ / 〃 をコメントとして扱ったソースのコンパイ ルに役に立って、しよう。 コード生成のバグ X68000 版 GCC て、は 32 ビット乗算命令を持 たない 68000 のために , 計算式の一方が定数 て、ある場合 , すべて shift, add, sub 命令を用 いて計算を行います。これによって構造体 の配列や多次元配列のアクセスがかなり改 善されるのてすが , このインプリメントが 十分て、なかったために List 3 のようなバグが 発生してしまいました。 ループ内部て、計算される i * 7 は ,bufC] [ ] をアクセスするための配列アドレス計算 を行う際の一連の shift, add の一部分て計算 結果を得ることが可能て、す。ところが -fstr ength-reduce を指定すると , この配列アド レス計算が最適化され , 削除されてしまい ます。この結果 , 計算途中結果を用いてい た i * 7 の結果がなくなってしまうといった 14 : ) 16 : / * 22 : ? 9 : 26 : ? 8 : 39 : * / コード生成のバグ LiSt ポートしていますが , これを X68000 版に復 活 ( ソースから削除してありました ) させる 際に List 4 のようなエンバグが起きてしまい ました。 なお , gcc. x は一 m68881 が指定されるとア センプラの前に fppp. x を起動します。て、すか ら , fppp. x がない場合には意味がありませ ん。ご注意ください。また , ー m68881 を指定 〃が #define され するとヾ HAVE68881 コンバイラの暴走 先ほどの定数乗法展開の処理がほかのバ グを持っていたため , List 5 のようなソース をコンノヾイルすると gcc ccl. x がノヾスエラー を起こしたり , 途中て、コンパイルを放棄し たりしました。 ドキュメント化されていない 追加機能と補足説明 このほかにいくっかの機能と改良が加え られています。また , 知っておくと便利な 機能も紹介します。 -fst 「 uct-st 「 ict-align List 6 の構造体 C010r は , 普通にコンパイ ルすると 1 構造体て 4 バイトのメモリが確保 され , sizeof ( C010r ) は 4 になります。て、す が , この C010r のメンバはすべて char て、 , の場合は厳密に偶数に境界整合の必要はあ りません。このようなときに -fstruct-stric t-align を指定した場合は , すべてのメンバ の境界整合条件のもっとも厳しいものに合 わせます。 1 : / * -fstrength-reduce を指定してあると、以下のような 配列添え字かのアドレス計算とループ内部での演算に 共通部分式があると誤ったコードを生成していた。 GCC のオリジナルバグではありません。 * / 6 : int bufC7][7]; 8 : bug0() int i, j,t for (i = 0 ; i く 7 : i + + ) for (j = 0 ; j く 7 : j + + ) buf[i]Cj] = 17 : —bug0 : 15 : 13 : 12 : 11 : 10 : 4 : 3 : 2 : バグて、した。 138 C M AGAZIN 1992 1 ー E68881 オプションバグ すが ) 。もともと , GCC はコプロセッサをサ るらしいて、す。私は使ったことがないのて、 とがて、きます ( その威力は凄まじいものがあ 用いて浮動小数点演算を高速に実行するこ 所持している場合は , ー m68881 オプションを このフリーウェアとコプロセッサポードを 換える fppp. x [ 注 1 ] というものがあります。 を直接ドライプする命令シーケンスに置き きない 68881 命令を , X68000 のコプロセッサ X68000 のフリーウェアに 68000 て、は実行て、 18 : 19 : 20 : 23 : 24 : 25 : 28 : 29 : 31 : 32 : 33 : 34 : 35 : 36 : 38 : movem. 1 d3/d4/d5, -(sp) moveq. 1 # 0 , d3 lea _buf, al moveq. 1 # 0 , d2 move. 1 d2, d0 moveq. 1 # 6 , dl lea 24 ( al , d0. 1 ) , a0 move. 1 d4, (a の subq. 響 # 4 , a0 dbra dl, ? 8 ext. 1 dl moveq. 1 # 28 , d5 add. 1 d5, d2 addq. 1 # 1 , d3 moveq. 1 # 6 , d5 cmp. 1 d3, d5 bge ? 9 movem. 1 ( (p) + , d3/d4/d5 rtS * d4 に何も値を入れてない ! !

5. 月刊 C MAGAZINE 1992年1月号

TabIe 1 loop. c のコンノヾイル結果 関数 TabIe 2 最適化ルーチンソースでのプロックプロファイル結果 プロファイルソース z : extra-loop. d, プロック総数 34 個 BlockNo addr offset exec 実行時間 回数 42 1 10 6416 44900 1 1 0 98 317 4567 3649 170 1 1 0 1 1 0 1 1 0 50906 2764 3838 9553 63 1 1 0 493 103 46 360 25 25 50 62 37 37 57 1 4 IOOP optimize static verify IOOP static note addr stored static can 」 ump intO range_p static scan IOOP IOOP skip over static count IOOP regs set static IOOP reg used before_p StatiC invariant_p static IOOP find reg equal static reg in basic block_p StatiC ignore_some_. _movables static force movables static combine movables static move movables static replace 「 egs static strength reduce static basic induction var StatiC general induction var StatiC find mem_givs static check dbra_loop static final biv value static rtx equal fO 「 loop_p static record giv atic last use this basic block StatiC count nonfixed reads static product cheap_p static emit ⅳ inc static emit ⅳ init COde static delete insn forces StatiC consec sets invariant_p static labels in range_p static regs match_p static check eliminate biv static can eliminate biv_p 16.54 4.39 0.39 2.60 1 1 .88 0.18 2.67 0.18 0.31 0.22 0 ℃ 2 0.01 0.02 0.14 3.03 3.45 4.35 0.23 0.27 0.80 0.08 0 ℃ 0 0.05 0 ℃ 2 0.00 0.03 0.00 0 ℃ 5 0.11 0.00 0.00 0.01 0.01 0.14 0.00 0 1 2 3 4 5 6 7 8 9 0 1 っム 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 1 2 っ ~ っ 4 っ 4 っ 4 っ 4 っ 4 っ 4 っムっっ 0 3 3 3 E4 EAO 36860 36872 E4EB2 E4ECO 36880 E4ED2 36892 E4EE4 368A4 E4EF6 368B6 E4F06 368C6 E4FIE 3 68 D E 368F6 E4F36 E4F3E 368FE E4F4E 3690E E4F5C 3691C E4F6A 3692A E4F76 36936 E4F8A 3694A E4F98 36958 E4FA6 36966 E4FB8 36978 E4FDO 36990 E4FE6 369A6 E4FF8 369B8 E500A 369CA E5018 369D8 3 E502E 3 369EE E503E 369FE 519 393 E504A 36AOA 393 E505A 36AIA E506A 36A2A E5076 36A36 E5086 36A46 3 36A56 3 E5096 E50A6 36A66 3 E50C8 36A88 5 1 9 E50DA 36A9A 10871 ( 注 ) BIock NO は List 8 の ? PB で始まるラベルがあるプロック。 add 「はプ ログラムの実行時の絶対アドレス , offset はプログラム先頭から のオフセットです。 exec はそのプロックの実行回数を示します 42 10871 5295 52 9 5 520 340 340 266 266 783 773 627 586 460 460 586 460 460 70 X68k 活用講座 145

6. 月刊 C MAGAZINE 1992年1月号

C プログラマ のための 新 OS 加グング入門 ー→@€@Y →→ー→ー→ 中島信行 第 1 6 回デバイスドライバのチェーンをたとる はテパイスドライバに関する裏技を少し紹介します。 FIG.SYS や ADDDRV コマンドで登録可能です。今回 MS - DOS ではユーサかテパイスドライバを CON テパイスドライバの先頭は N LJL デバイス よく知られているように MS-DOS て、は CO NFIG. SYS や ADDDRV コマンドて、テ。バイス ドライバを登録することにより , 既存のキ ャラクタデバイスを差し換えることがて、き ます。日本のパソコンて、必要不可欠な日本 語 FEP は既存の CON デバイスを差し換える タイプのものが少なくありません。 この原理は非常に簡単て、す。 MS-DOS は デバイスドライバのチェーンを必ず先頭か らたどって , 最初に見つけたデバイス名の デバイスを採用します。 たとえば , CONi•バイスがふたつ以上あ っても , 最初の CON デバイスだけを採用す るわけて、す。したがって , 後から登録する デバイスをデバイスドライバのチェーンの 最初のほうに割り込ませるとよいことにな ります。 実際には , デバイスドライバの先頭は NU L デバイスて、あり , CONFIG. SYS や ADDD RV コマンドて、登録されるデバイスは NUL デ 84 C MAGAZINE 1 2 1 バイスの次に登録されます ( Fig. 1 ) 。 7 テパイスへッダアドレスの 取得法その 1 それて、は , NUL デバイスのデバイスへッ ダアドレスはどのようにして取得て、きるの て、しようか。残念ながら , DOS ファンクシ ョンにはこのような機能を持つものはあり ません。 そこて、 , 筆者が独自に解析した手法をふ Fig. 1 テパイスドライバのチェーン NEWDEV を追加 たつ紹介します。 いるものが少なくありません。 この DOS ファンクションのお世話になって 能を使用する筆者のユーティリティて、は , を提供してくれます。 MS-DOS の特殊な機 が , MS-DOS のもっともべーシックな情報 ン 52h は非公開の DOS ファンクションて、す スの取得を使用します。 DOS ファンクショ ョン 52h(TabIe 1 ) の内部変数領域のアドレ まず , ひとつ目の方法は DOS ファンクシ

7. 月刊 C MAGAZINE 1992年1月号

C010r のメンバはすべて char て、すから , s izeof ( C010r ) は 3 , sizeof(buf) は 30 になりま 出力コードの改善とヘルプ 5 : 19 : / * 24 : { す。 2 : 3 : 4 : 7 : 10 : 11 : 12 : 14 : 15 : 16 : 20 : 22 : 23 : 24 : 25 : 26 : 28 : 29 : 30 : 31 : 2 : 3 : 4 : 5 : 7 : 8 : 9 : 11 : 13 : 14 : 19 : 20 : 22 : 25 : 26 : シフトを行うコードを , 16 ~ 24 ビットシ LiSt ー m68881 オプションバグ 1 : / * ー m68881 を指定すると fpa のレジスタをスタックから 復帰するときオフセットを間違う。ー m68881 を復活 させた時のエンバグでした。 fmovem. x fp2, -(sp) 1 ink a6, # 0 f00 : return X * y; for (i = 0 ; i く int i ; double y = 0.0 : double x = 0.0 : 8 : double foo(void) 6 : double dl(); 5 : double d0(); i 十十 ) move. 1 d3, ー (sp) fmovecr #$f, fp2 move. 1 (sp) + , dl move. 1 ー 16 ( a6 ) , d3 fmovem. x ー 16 ( a6 ) , fp2 * 間違い ! ! unlk a6 r ts List コンバイラの暴走 1 : / * -fforce-addr を指定してコンパイルするとバスエラー を起こしたり、コンパイルを中断したり etc. の不都合が foo *n = bugs() : 23 : void bug—test (int x, int の return f : f = &data[data—num + + ] : f00 *f ; 16 : inline f00 *bugs() 15 : / * inline 関数にしなければコンパイル OK です * / int data_num; 12 : f00 dataL50] : 10 : } f00 ; short dummyC3] : struct st *next; short x, y; typedef struct S t 起きる例 * / フトについて swap を用いて高速て、行うよう に変更しました。 GCC のようなビットフィ ールドを用いているソースについて有効て、 す。そのほかに環境変数 GCC OPTION に 、、 0 〃が設定してあると定数て、の変数設定を 少し最適化します。 それから , スタックフレームが 32K バイト を越えたら警告するようにしてあります。 「舍計なお世話」の方もおられるてしようが , 不用意に巨大な配列を自動変数に確保して 暴走させることがメモリに比較的制限のな い X68000 て、は多いようなのて、つけておきま また , gcc. x がヘルプファイルをサポート しました。ソースファイルを指定しないて とすればヘルプが表示されます。 スイッチの数が多いのて , 簡易版てはあり ますが , 普通に使う機能についてはヘルプ ファイルて、十分だと思います。ヘルプファ イルは gcc. x が存在するディレクトリから g cc. hlp というファイルを探して表示するだけ て、す。これが存在しない場合は何もせずに 終了します。 知っておくと便利なタグジャンプ X68000 に付属の ED. X を使う場合は , 環境 変数 MARIKO に文字、、 D 〃 , MARINA に E D. X, GCC OPTION にヾ E 〃を設定してお きます。工ラーがあると自動的にエデイタ が起動されるのて、 , 直したいエラー表示の 上にカーソルを移動して亘を押し , その 後を押します。画面が切り換わってソー スの該当位置にカーソルが飛びます。ソー スを修正して亘十回てセープしたら , 再 度自動的にコンパイルしなおします。 これをエラーがなくなるまて、繰り返せば いいのてす。プリプロセッサ段階てはこの 機能は働きません。 パソコン通信上て、もっとも数が多かった 質問は , 「新しい GCC ては疑似統合環境てタ グジャンプてきなくなった」というものてし た。工ラーメッセージのデフォルトが Nem X68k 活用講座 139

8. 月刊 C MAGAZINE 1992年1月号

特集いと G ど , 優れた長所が数多いのもまた確かて、あ のテクニックにしがみつく」という意味て、は OOP 言語としての成熟度も急速に高まりつ る。そして , C プログラマにとって最大のメ なく , 新たなパラダイムの中て、もそれを活 仕様が固まり , 標準クラスラ つある 0 「コロロ リットは , 「 C て、の経験がもっとも活かせる かすことがて、きるのて、ある。 イプラリが普及すれば , こしばらく , OOP 言語て、ある」ことだと筆者は思う。「 C 風 さらに , たび重なる拡張により , C 十十の C 十十からは目が離せない Borland C 十十クラスライプラリを用いた例 い。一方 , bcd 型を用いれば誤差は生じ ず , 正しい結果が得られる。 1 : / / Bor land C + + クラスライブラリを用いた例 bcd 型は 17 桁の精度を持ち , 10 ー 125 から 2 : / / Compile: 3 : / / bcc -l/borlandc/classl ib/include f00. c} 125 10 までの数値を表すことができる。 bc 4 : / / /borlandc/classlib/lib/tclasss. lib 5 : d 型にはメンバ関数 re 引が定義してあり , 6 : #include く iostream. h 〉 7 : #include く stdlib. h> ngdoub 厄型に変換できる。またストリ 8 : #include く string. h> ーム型も bcd 型に対応しているので , 数値 9 : 10 : / / クラスライブラリへッダ を表示したい場合には , *cout くく bcd 11 : #include く dict. h> / / class Dictionary / / class Association 12 : #include く assoc. h 〉 i ; 〃のようにしてもよい。 13 : #include く strng. h 〉 / / class String 14 : #include く sortable. h> / / class Sortable double や long doub 厄型から bcd 型に変 15 : 換するときには , 第 2 バラメータに示す値 18 : int val; の桁で小数点以下の精度を決めることが できる。有効数字を陽に指定しないと , 21 : Number(const Number& 0 ) { val = 0. val ; } int isEqual (const 0bject& 0 ) const { 22 : 正しく bcd 型に変換されないことがある。 = isA() & & val = ((Number&)o). val; return 0. isA() 23 : 24 : コンテナクラスライプラリ int isLessThan(const Object& 0 ) const { 25 : return val く ((Number&)o). val; 26 : コンテナクラスライプラリは , ハッシ char* name0f() const { return ” Number ” : } 28 : cIassType isA() const { return longClass + 1 : 29 : リストなど , ュ表 , スタック , キュー hashVaIueType hashVaIue() const ( return val ・ 30 : int getValue() const { return val : } オプジェクトを入れる「入れ物」のライプ void printOn(ostream& s) const { s くく val; ) 32 : 33 : } : ラリである。 Fig. A のような階層構造をし 34 : 35 : int main() ており , 抽象クラスの Object から派生した 36 : { Dictionary dict; クラスについて集合を扱うことができる。 = 80 : const bufsiz 38 : char buf[bufs iz] ; 39 : したがって , ジェネリッククラスのよう 40 : に , 任意のクラスについて集合操作を定 cout くく” keyword ( ' end' t0 end) 42 : 義できるわけではない。 cin 〉 > buf; cin. get(); 43 : 44 : 実際に , この Dictionary クラスを用いた if (strcmp(buf, ” end ” ) 45 : break; 例を ListB に示す。このプログラムは , 変 ) else { String *key = new String(buf) ; 48 : 数とその値を管理するものである。新た Association &ap = dict. lookup(*key) : 49 : if ()p ! = NOOBJECT) { / / 登録済みー〉値表示 50 : に SortabIe から Number というクラスを派 cout くく buf くく cout くく ( (Number&)ap. value()). getValue() : 52 : 生して ,String と Number の連想リスト (A cout くく” \ n ”・ 53 : 54 : delete key; ssociation List) を作成し , Dictionary に追 / / 新規登録 } else { 55 : cout くく” value 56 : 加している。 cin 〉〉 buf; cin. get(); Number *val = new Number(at0i(buf)) ; 58 : キーポードから変数名を入力し , もし dict. add(*(new Association(*key, *val))) ; 59 : すでに変数が登録されていれば , その値 60 : を表示し , 登録されていなければ , 値を 入力して新たに登録する。 LiSt / / 辞書 朝 特集 C 十十と DJGPP 65