[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]

# 8アプリケーション内の条件処理コードの確認

この章では，アプリケーション内の条件処理コードに対して，VAXアーキテクチャと Alphaアーキテクチャの違いがどのような影響を与えるかについて説明します。

# 8.1概要

ほとんどの場合，アプリケーションの条件処理コードは Alphaシステムでも正しく機能します。特に，FORTRANのENDやERR，IOSTAT指定子など， アプリケーション開発において， 高級言語で提供される条件処理機能を使用している場合には，問題はありません。 これらの言語機能はアーキテクチャ固有の条件処理機能からアプリケーションを分離します。

しかし，Alpha条件処理機能とそれに対応する VAX条件処理機能の間にはいくつかの違いがあり， 場合によってはソース・コードを変更しなければなりません。次の場合には， ソース・コードの変更が必要です。

- メカニズム・アレイの形式を変更する場合

- システムから戻された条件コードを変更する場合

- アプリケーション内の条件処理に関連する他の作業を実現する方法を変更する場合。 たとえば，例外通知を許可し，実行時に条件処理ルーチンを動的に指定する場合など

この後の節では，これらの変更について詳しく説明し， ソース・コードの変更が必要かどうかを判断するのに役立つガイドラインも示します。

# 8.2動的条件ハンドラの設定

OpenVMS Alphaの実行時ライブラリ(RTL)にはLIB$ESTABLISHルーチンがありませんが， OpenVMS VAXのRTLにはこのルーチンがあります。OpenVMS Alphaの呼び出し規則により， 条件ハンドラの設定はコンパイラによって行われます。

条件ハンドラを動的に設定しなければならないプログラムのために，一部の Alpha言語では，LIB$ESTABLISHの呼び出しが特別な方法で取り扱われ，実際に RTLルーチンを呼び出さずに適切なコードを生成します。次の言語は，対応する VAX言語と互換性のある方法でLIB$ESTABLISHをサポートします。

- DEC CとDEC C++

  OpenVMS Alphaシステム用のDEC CとDEC C++は， LIB$ESTABLISHを組み込み関数として取り扱いますが，OpenVMS VAXまたは OpenVMS AlphaシステムでLIB$ESTABLISHを使用することは望ましくありません。 CおよびC++のプログラマは，LIB$ESTABLISHの代わりに VAXC$ESTABLISHを呼び出すようにしてください(VAXC$ESTABLISHは， OpenVMS Alphaシステム用のDEC CとDEC C++で提供される組み込み関数です)。

- Digital Fortran

  Digital Fortranでは，LIB$ESTABLISHおよび LIB$REVERT内部関数に対する宣言が可能であり，これらを Digital Fortran RTL固有のエントリ・ポイントに変換します。

- DEC Pascal

  DEC Pascalでは，ESTABLISHとREVERTという組み込みルーチンが提供され， LIB$ESTABLISHおよびLIB$REVERTの代わりに使用できます。 LIB$ESTABLISHを宣言して使用しようとすると，コンパイル時に警告が出されます。

- MACRO-32

  MACRO-32コンパイラは， LIB$ESTABLISHの呼び出しがソース・コードに指定されている場合， これを呼び出そうとします。

  MACRO-32プログラムが0(FP)のルーチン・アドレスを格納することにより， 動的ハンドラを設定する場合には，これらのプログラムは， OpenVMS Alphaシステムでコンパイルした場合も正しく動作します。しかし， CALL_ENTRYルーチンの内部からでなければ，JSB (Jump to Subroutine)ルーチンの内部から条件ハンドラ・アドレスを設定することはできません。

# 8.3依存している条件処理ルーチンの確認

ユーザ作成条件処理ルーチンの呼び出しシーケンスは，Alphaシステムでも VAXシステムのときと同じです。条件処理ルーチンは， 例外条件を通知するときにシステムが戻すデータをアクセスするために 2つの引数を宣言します。システムはシグナル・アレイとメカニズム・アレイという 2つの配列を使用して，どの例外条件がシグナルを起動したかを識別する情報を伝達し， 例外が発生したときのプロセッサの状態を報告します。

シグナル・アレイとメカニズム・アレイの形式はシステムで定義され， 『OpenVMS Programming Concepts Manual』に説明されています。Alphaシステムでは， シグナル・アレイに戻されるデータとその形式はVAXシステムの場合と同じです。 図 8-1を参照してください。

### 図 8-1　VAXシステムとAlphaシステム上の32ビット・シグナル・アレイ

次の表はシグナル・アレイ内の各引数を示しています。

引数 | 説明
--- | ---
引数の数 | AlphaシステムでもVAXシステムでも， この引数には正の整数が格納され，配列内でこの後に続くロングワードの数を示す。
状態コード | AlphaシステムでもVAXシステムでも， この引数は32ビットのコードであり， ハードウェアまたはソフトウェア例外条件を一意に識別する。条件コードの形式は Alphaシステムでも変更されておらず， 『OpenVMS Programming Interfaces: Calling a System Routine』 に説明されているとおりである。しかし，Alphaシステムは VAXシステムで戻されるすべての条件コードをサポートするわけではなく， さらにVAXシステムでは戻されない条件コードを定義している。 Alphaシステムで戻すことができないVAX条件コードについては 第8.4節を参照。
オプション・メッセージ・ シーケンス | これらの引数は戻される例外に関する追加情報を提供し， これは各例外に応じて異なる。VAX例外に対するこれらの引数については， 『OpenVMS Programming Concepts Manual』を参照。
プログラム・カウンタ (PC) | 例外がトラップである場合には， 例外が発生したときに次に実行される命令のアドレス。例外がフォルトの場合には， 例外の原因となった命令のアドレス。Alphaシステムでは，この引数にはPCの下位 32ビットが格納される(Alphaシステムでは，PCは64ビットの長さである)。
プロセッサ・ステータス・ ロングワード(PSL) | フォーマッティングした32ビットの引数であり， 例外が発生したときのプロセッサの状態を記述する。Alphaシステムでは， この引数にはAlphaの64ビットのプロセッサ・ステータス(PS)・クォドワードの下位 32ビットが格納される。

Alphaシステムでは，メカニズム・アレイにはVAXの場合と同様のデータが戻されます。 しかし，その形式は異なります。Alphaシステムで戻されるメカニズム・アレイには， 浮動小数点スクラッチ・レジスタだけでなく， 整数スクラッチ・レジスタの内容も保存されます。さらに，Alphaのレジスタは 64ビットの長さであるため，メカニズム・アレイは，VAXシステムのようにロングワード (32ビット)ではなく，クォドワード(64ビット)で構成されます。 図 8-2はVAXシステムと Alphaシステムでのメカニズム・アレイの形式を比較しています。

### 図 8-2　VAXシステムと Alphaシステムでのメカニズム・アレイ :(クリックで表示)

次の表はメカニズム・アレイ内の各引数を示しています。

引数 | 説明
--- | ---
引数の数 | VAXシステムでは， この引数には正の整数が格納され，配列内でその後に続くロングワードの数を示す。 Alphaシステムでは，この引数はメカニズム・アレイ内のクォドワードの数を示し， 引数カウント・クォドワードの数(Alphaシステムでは常に43)を示すわけではない。
フラグ | Alphaシステムでは， この引数には追加情報を伝達するためのさまざまなフラグが格納される。たとえば， ビット0がセットされている場合には，プロセスがすでに浮動小数点演算を実行し， 配列内の浮動小数点レジスタが正しいことを示す( VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
フレーム・ポインタ(FP) | VAXシステムでもAlphaシステムでも， この引数には条件ハンドラを設定したスタックの呼び出しフレームのアドレスが格納される。
深さ | VAXシステムでもAlphaシステムでも，この引数には， 例外を発生させたフレームを基準にして， 条件処理ルーチンを設定したプロシージャのフレーム番号を表現する整数が格納される。
リザーブ | 予約されている。
ハンドラ・データ・アドレス | Alphaシステムでは，この引数には， ハンドラが存在する場合はハンドラ・データ・クォドワードのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
例外スタック・フレーム・アドレス | Alphaシステムでは， この引数には例外スタック・フレームのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
シグナル・アレイのアドレス | Alphaシステムでは，この引数にはシグナル・アレイのアドレスが格納される (VAXシステムのメカニズム・アレイにはこれに対応する引数はない)。
レジスタ | VAXシステムでもAlphaシステムでも， メカニズム・アレイにはスクラッチ・レジスタの内容が格納される。 Alphaシステムでは，この引数にはるかに大きなレジスタ・セットが格納され， 対応する浮動小数点レジスタも格納される。

対処方法

32ビット・シグナル・アレイはAlphaシステムとVAXシステムとで同じであるため， 条件処理ルーチンのソース・コードを変更する必要はないでしょう。しかし， メカニズム・アレイは変更されているため， ソース・コードを変更しなければならないかもしれません。特に， 次のことを確認してください。

- 条件処理ルーチンのソース・コードを調べ， メカニズム・アレイ内の配列要素のサイズや配列要素の順序に関して何らかの仮定を設定していないかどうかを確認してください。

- アプリケーションの条件処理ルーチンで特定の数のスタック・フレームを巻き戻すために depth 引数を使用している場合には， ソース・コードを変更しなければならない可能性があります。 アーキテクチャが変更されたため，Alphaシステムで戻される depth 引数は VAXシステムで戻される引数と異なる可能性があります(メカニズム・アレイの depth 引数は，例外が発生したフレームを基準にして， ハンドラを設定したプロシージャとの間のフレームの数を示します)。

  SYS$UNWINDシステム・サービスに対してdepth引数のアドレスを指定することにより， 例外処理ハンドラを設定したフレームまで巻き戻すアプリケーションや， SYS$UNWINDシステム・サービスの省略時のdepth引数を使用することにより， 例外処理ハンドラを設定したフレームの呼び出し側まで巻き戻すアプリケーションは， 今後も正しく動作します。depthを負の値として指定した場合には， 例外ベクタを示します(VAXシステムの場合と同じ)。

例 8-1はCで作成した条件処理ルーチンを示しています。

### 例 8-1条件処理ルーチン

         #include  <ssdef.h>
         #include  <chfdef.h>
            .
            .
            .
      【1】 int cond_handler( sigs, mechs )
            struct  chf$signal_array  *sigs;
            struct  chf$mech_array   *mechs;
         {
              int status;

      【2】   status = LIB$MATCH_COND(sigs->chf$l_sig_name, /* returned code */
                                      SS$_INTOVF);          /* test against  */

      【3】   if(status != 0)
              {
                  /*  ...Condition matched.  Perform processing.  */
                  return SS$_CONTINUE;
              }
              else
              {
                  /*  ...Condition does not match. Resignal exception. */
                  return SS$_RESIGNAL;
              }
         }

次のリストの各項目は 例 8-1に示した番号に対応しています。

【1】 | このルーチンは， システムがシグナル・アレイとメカニズム・アレイに戻すデータをアクセスするために， sigsとmechsという2つの引数を定義します。このルーチンは前もって定義されている 2つのデータ構造を使用して，引数を宣言します。2つのデータ構造とは chf$signal_arrayとchf$mech_arrayであり，システムによって CHFDEF.Hヘッダ・ファイルに定義されています。
【2】 | この条件処理ルーチンは LIB$MATCH_CONDランタイム・ライブラリ・ルーチンを使用することにより， 戻された条件コードと，整数オーバーフローを識別する条件コード (SSDEF.Hに定義されているコード)を比較します。 条件コードはシステム定義のシグナル・データ構造のフィールドとして参照されます (CHFDEF.Hに定義されています)。
【3】 | LIB$MATCH_CONDルーチンは， 一致する条件コードを検出したときにゼロ以外の結果を戻します。 条件処理ルーチンはこの結果をもとに，異なるコード・パスを実行します。

# 8.4例外条件の識別

アプリケーションの条件処理ルーチンは， シグナル・アレイに戻された条件コードを確認することにより， どの例外が通知されているかを識別します。次のプログラムの一文は 例 8-1から抜粋したものであり， 条件処理ルーチンがランタイム・ライブラリ・ルーチン LIB$MATCH_CONDを使用することにより， この作業をどのような方法で実現できるかを示しています。

         status = LIB$MATCH_COND( sigs->chf$l_sig_name,  /* returned code */
                                           SS$_INTOVF);  /* test against  */

このメカニズムはAlphaシステムでも変更されていません。 32ビットの条件コードの形式とシグナル・アレイ内での位置は， VAXシステムの場合と同じです。しかし，条件処理ルーチンが VAXシステムで受け取っていた条件コードは Alphaシステムでは意味がないでしょう。アーキテクチャが異なるため， VAXシステムで戻されていた一部の例外条件は，Alphaシステムではサポートされません。

ソフトウェア例外の場合には，Alphaシステムは VAXシステムの場合と同じ例外をサポートします。このことについては， オンライン・ヘルプ・メッセージ・ユーティリティまたは 『OpenVMS system messages documentation』に示されています。しかし， ハードウェア例外はソフトウェア例外よりアーキテクチャに依存する部分が多く， 特に算術演算例外はアーキテクチャに依存しています。 VAXシステムでサポートされていたハードウェア例外の一部( 『OpenVMS Programming Concepts Manual』を参照)だけが Alphaシステムでもサポートされます。さらに，Alphaアーキテクチャでは， VAXアーキテクチャでサポートされないいくつかの追加された例外を定義しています。

表 8-1は，Alphaシステムでサポートされない VAXハードウェア例外と，VAXシステムでサポートされない Alphaハードウェア例外を示しています。アプリケーションの例外処理ルーチンがこれらの VAX固有の例外をテストする場合には，対応する Alpha例外をテストするためのコードを追加する必要があります( Alphaシステムでの算術演算例外のテストについての詳しい説明は， 第8.4.1項を参照してください)。

> 注意
>   Alphaシステムで実行されるトランスレートされたVAXイメージは，これらの VAX例外を戻すことができます。

### 表 8-1　アーキテクチャ固有のハードウェア例外 :(クリックで表示)

## 8.4.1Alphaシステムでの算術演算例外のテスト

VAXシステムでは，アーキテクチャは算術演算例外が同期的に報告されるようにします。 つまり，例外(オーバーフローなど)の原因となったVAX算術演算命令は， ただちに例外処理ハンドラを開始し，後続の命令は実行されません。 例外ハンドラに報告されるプログラム・カウンタ(PC)は， 例外の原因となった算術演算命令のPCです。このため， アプリケーション・プログラムは，たとえば，メイン・シーケンスを再開し， 例外の原因となった操作を同等の操作または別の操作によってエミュレートするか， 置換することができます。

Alphaシステムでは，算術演算例外は非同期的に報告されます。つまり， アーキテクチャの実現方法により，例外の原因となった命令より後の多くの命令 (分岐やジャンプも含む)を実行できます。これらの命令は， 例外の原因となった命令が使用していたオペランドの上に重ね書きする可能性があるため， 例外を解釈したり，修正するのに必要な情報が失われてしまいます。 例外ハンドラに報告されるPCは，例外の原因となった命令のPCではなく， その後に実行された命令のPCです。 例外がアプリケーションの例外ハンドラに報告される時点では， ハンドラは入力データを修正しており， 命令を再起動することができない可能性があります。

このように，算術演算例外の報告方法が基本的に異なるため，Alphaシステムでは， SS$_HPARITHという1つの条件コードを定義し， これによってすべての算術演算例外を示します。たとえば， 整数オーバーフロー例外が発生したときに処理を実行する条件処理ルーチンがアプリケーションに含まれている場合， VAXシステムでは，SS$_INTOVR条件コードが例外処理ルーチンに渡されます。 Alphaシステムでは，この例外はSS$_HPARITHという条件コードによって示されます。 このため，アプリケーションの条件処理ルーチンは， Alpha算術演算例外を対応するVAX例外と誤って解釈することがありません。 処理を行うアプリケーションが，アーキテクチャ固有である可能性があるため， このことは重要です。

図 8-3は SS$_HPARITH例外シグナル・アレイの形式を示しています。

### 図 8-3　SS$_HPARITH例外シグナル・アレイ

このシグナル・アレイには，SS$_HPARITH例外の固有の3つの引数が格納されます。 それは整数レジスタ・ライト・マスク，浮動小数点レジスタ・ライト・マスク， および例外サマリです。整数および浮動小数点レジスタ・ライト・マスクは， 例外サマリのビットをセットした命令のターゲットであったレジスタを示します。 マスク内の各ビットはレジスタを表現します。例外サマリは最初の 7ビットにフラグをセットすることにより，通知される例外のタイプ( 1つ以上)を示します。表 8-2 はこれらの各ビットがセットされているときの意味を示しています。

### 表 8-2　例外サマリ引数のフィールド

ビット | 意味
--- | ---
0 | ソフトウェアは正常終了した。
1 | 浮動小数点演算，変換，または比較操作に誤りがある。
2 | 浮動小数点除算で0による除算を実行しようとした。 0による整数除算は報告されないので注意しなければならない。
3 | 浮動小数点演算または変換操作で宛先の指数部がオーバーフローした。
4 | 浮動小数点演算または変換操作で宛先の指数部がアンダーフローした。
5 | 浮動小数点演算または変換操作で正確な算術演算結果と異なる結果が報告された。
6 | 浮動小数点数値から整数への変換操作または整数算術演算で宛先の精度がオーバーフローした。

対処方法

算術演算例外に応答して処理を実行する条件処理ルーチンを Alphaシステムで実行するために変更しなければならないかどうかを判断する場合には， 次のガイドラインに従ってください。

- アプリケーション内の条件処理ルーチンが， 発生した算術演算例外の数だけを数える場合や， 算術演算例外が発生したときに強制終了する場合には， Alphaシステムで例外が非同期的に報告されることは問題になりません。 これらの条件処理ルーチンは， SS$_HPARITH条件コードのテストを追加するだけで十分です。

- アプリケーションで例外の原因となった操作を再起動しようとする場合には， コードを変更するか，またはコンパイラ修飾子を使用することにより， 算術演算例外が正確に報告されるようにしなければなりません。大部分の Alphaコンパイラは，互換性を保つために， 例外の正確な報告を行うかどうかをプログラマがコンパイル時に指定するためのコンパイラ・オプションを持っています (DEC C: /IEEE_MODE，DEC Fortran: /IEEE_MODEまたは/SYNCHRONOUS_EXCEPTIONS)。

  ただし，これらの命令を指定すると，性能が低下する可能性があります。 例外の正確な報告がアプリケーションの一部の操作でのみ必要な場合は， そのような操作を含んでいる部分のコンパイルだけにこのオプションを使用するようにしてください。 詳細については，使用するコンパイラのマニュアルを参照してください。

- トランスレートされたイメージで算術演算例外が正確に報告されることを保証するには， イメージをトランスレートするときにVESTコマンド・ラインに /PRESERVE=FLOAT_EXCEPTIONS修飾子を指定します。この修飾子を使用した場合には， VESTユーティリティは，浮動小数点フォルトの原因となる各命令を実行した後， 例外を報告できるようなコードを生成します。しかし，この修飾子を使用すると， トランスレートされたイメージの性能が低下する可能性があります。 VESTコマンドの使い方についての詳しい説明は， 『DECmigrate for OpenVMS AXP Systems Translating Images』を参照してください。

  > 注意
  >   Alphaシステムで実行されるトランスレートされたVAXイメージは， 算術演算例外条件も含めて，VAX例外条件を戻します。

## 8.4.2 データ・アラインメント・トラップのテスト

Alphaシステムでは，アラインされていないアドレスをオペランドとして受け付ける Alpha命令(LDQ_U)を使わずに， 自然なアラインメントになっていないアドレスを使用して， レジスタとの間でロングワードまたはクォドワードをロード/ストアしようとする操作を実行すると， データ・アラインメント・トラップが発生します (データ・アラインメントについての詳しい説明は， 第7章を参照してください)。

Alphaシステムのコンパイラは通常，次の操作を実行することにより， アラインメント・フォルトの発生を防止します。

- 省略時の設定により，静的データを自然な境界にアラインします (この省略時の動作はコンパイラ修飾子を使用することにより変更できます)。

- コンパイル時に正しくアラインされていないことがわかっているデー タに対して，特殊なインライン・コード・シーケンスを生成します。

しかし，動的に定義されるデータをコンパイラがアラインすることはできません。 したがってこのような場合は，アラインメント・フォルトが発生する可能性があります。

アラインメント例外は条件コードSS$_ALIGNによって示されます。 図 8-4は， SS$_ALIGN例外によって戻されるシグナル・アレイの要素を示しています。

### 図 8-4　SS$_ALIGN例外のシグナル・アレイ

このシグナル・アレイには，SS$_ALIGN例外固有の2つの引数が格納されます。 それは仮想アドレスとレジスタ番号です。仮想アドレスには， アクセスしているアラインされていないデータのアドレスが格納されます。 レジスタ番号は操作の対象となるレジスタを示します。

対処方法

- アプリケーションの開発中にアラインメント・フォルトを検出するには， この例外条件を用います。このようにすれば， この段階でアプリケーションの性能に影響するデータ・アラインメントの問題を修正することができます。 この例外が報告されているということは， アプリケーションはデータ・アラインメントの問題によって， 性能に影響を受けているということになります。

# 8.5条件処理に関連する他の作業の実行

いままでに述べてきた条件処理ルーチンの問題に加えて， 条件処理を含むアプリケーションは， システムに対して条件処理ルーチンを設定するなどの他の操作を実行しなければなりません。 ランタイム・ライブラリには， アプリケーションでこれらの操作を実行するためのルーチンが準備されています。 たとえば，アプリケーションでランタイム・ライブラリ・ルーチン LIB$ESTABLISHを呼び出すことにより， 例外が通知されるときに実行される条件処理ルーチンを識別(または設定)できます。

VAXアーキテクチャとAlphaアーキテクチャには相違点があり， 両方のアーキテクチャの呼び出し規則にも違いがあるため， これらの多くの操作の実現方法は同じではありません。 表 8-3は VAXシステムで提供されるランタイム・ライブラリ条件処理サポート・ルーチンと， Alphaシステムではどのルーチンがサポートされるかを示しています。

### 表 8-3　ランタイム・ライブラリ条件処理サポート・ルーチン :(クリックで表示)

対処方法

次のリストは， ランタイム・ライブラリ・ルーチンを使用するアプリケーションにおけるガイドラインを示しています。

- アプリケーションで例外報告を可能にするランタイム・ライブラリ・ルーチンのいずれかを呼び出すことにより， 例外の通知を許可している場合には，ソース・コードを変更しなければなりません。 これらのルーチンはAlphaシステムではサポートされません。しかし， 特定のタイプの算術演算例外は Alphaシステムで常に通知されるように設定されています。 次のタイプの算術演算例外は常に通知されます。

  - 無効な浮動小数点演算

  - ゼロによる浮動小数点除算

  - 浮動小数点オーバーフロー

  省略時の設定により通知されないように設定されている例外は， コンパイル時に通知されるように設定しなければなりません。

- アプリケーションでランタイム・ライブラリ・ルーチン LIB$ESTABLISHを呼び出すことにより，条件処理ルーチンを指定する場合には， ソース・コードを変更する必要はありません。 Alphaシステムの大部分のコンパイラは互換性を維持するために， LIB$ESTABLISHルーチンへの呼び出しを受け付けます。コンパイラは「現在の」 条件ハンドラを指す変数を，スタック上に作成します。 LIB$ESTABLISHはこの変数を設定します。LIB$REVERTはこの変数を消去します。 これらの言語に対して静的に設定されたハンドラは，この変数の値を読み込み， どのルーチンを呼び出すかを判断します。

たとえば，例 8-2に示したプログラムは FORTRANで作成されており，条件コードSS$_INTOVFを指定することにより， 整数オーバーフローをテストする条件処理ルーチンを指定するために， RTLルーチンLIB$ESTABLISHを使用しています。VAXシステムでは， 整数オーバーフローの検出を可能にするために，プログラムをコンパイルするときに /CHECK=OVERFLOW修飾子を指定しなければなりません。

このプログラムをAlphaシステムで実行するには，条件コードをSS$_INTOVFから SS$_HPARITHに変更しなければなりません (オーバーフローのタイプはシグナル・アレイ内の例外サマリ引数を調べることにより判断できます。 詳しくはコンパイラに関する解説書を参照してください)。VAXシステムの場合と同様に， オーバーフロー検出を可能にするためにはコンパイル・コマンド・ラインに /CHECK=OVERFLOW修飾子を指定なければなりません。DEC Fortranは LIB$ESTABLISHルーチンを組み込み関数として受け付けるため， このルーチンの呼び出しを削除する必要はありません。

### 例 8-2条件処理プログラムの例

         C       This program types a maximum value of integers
         C       Compile with /CHECK=OVERFLOW and the /EXTEND_SOURCE qualifiers

                 INTEGER*4 int4
                 EXTERNAL HANDLER
                 CALL LIB$ESTABLISH (HANDLER) 【1】

                 int4=2147483645
                 WRITE (6,*) ' Beginning DO LOOP, adding 1 to ', int4
                 DO I=1,10
                   int4=int4+1
                   WRITE (6,*) ' INT*4 NUMBER IS  ', int4
                 END DO
                 WRITE (6,*) ' The end ...'
                 END

         C       This is the condition-handling routine

                 INTEGER*4 FUNCTION HANDLER (SIGARGS, MECHARGS)
                 INTEGER*4 SIGARGS(*),MECHARGS(*)
                 INCLUDE '($FORDEF)'
                 INCLUDE '($SSDEF)'
                 INTEGER INDEX
                 INTEGER LIB$MATCH_COND

                 INDEX = LIB$MATCH_COND (SIGARGS(2), SS$_INTOVF) 【2】
                 IF (INDEX .EQ. 0 ) THEN
                    HANDLER = SS$_RESIGNAL
                 ELSE IF (INDEX .GT. 0) THEN
                    WRITE (6,*) 'Arithmetic exception detected...'
                    CALL LIB$STOP(SIGARGS(1))
                 END IF
                 END

次のリストの各項目は 例 8-2に示されている番号に対応しています。

【1】 | この例では，条件処理ルーチンを指定するためにLIB$ESTABLISHを呼び出します。
【2】 | Alphaシステムでは，条件コードをSS$_INTOVFから SS$_HPARITHに変更しなければなりません。条件処理ルーチンは LIB$STOPルーチンを呼び出すことにより，プログラムの実行を終了します。

次の例は，例 8-2に示したプログラム名をコンパイル， リンク，および実行する方法を示しています。

         $ FORTRAN/EXTEND_SOURCE/CHECK=OVERFLOW  HANDLER_EX.FOR
         $ LINK  HANDLER_EX
         $ RUN   HANDLER_EX
          Beginning DO LOOP, adding 1 to 2147483645
          INT*4 NUMBER IS    2147483646
          INT*4 NUMBER IS    2147483647
         Arithmetic exception detected...
         %TRACE-F-TRACEBACK, symbolic stack dump follows
          Image Name   Module Name     Routine Name    Line Number  rel PC      abs PC
          INT_OVR_HAND INT_OVR_HANDLER HANDLER                1637 00000238    00020238
          DEC$FORRTL                                             0 000651E4    001991E4
         ----- above condition handler called with exception 00000504:
         %SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=00000001, Fmask=00000
         000, summary=40, PC=000200E0, PS=0000001B
         -SYSTEM-F-INTOVF, arithmetic trap, integer overflow at PC=000200E0, PS=0000001B
         ----- end of exception message
                                                                0 84FE9FFC    84FE9FFC
         INT_OVR_HAND INT_OVR_HANDLER INT_OVR_HANDLER          15 000000E0    000200E0
                                                                0 84EFD918    84EFD918
                                                                0 7FF23EE0    7FF23EE0

[ 前のページ ] [ 次のページ ] [ 目次 ] [ 索引 ] [ DOC Home ]