前へ | 次へ | 目次 | 索引 |
DEC C および DEC C ランタイム・ライブラリ (RTL) は 64 ビット・アドレッシングを完全にサポートしているため, OpenVMS Alpha の 64 ビット・アプリケーション,ライブラリ,およびシステム・コードをプログラミングするには,C 言語が適しています。 64 ビット・ポインタは既存の C コードにシームレスに組み込むことができます。また,自然な C コーディング・スタイルで, OpenVMS Alpha が提供する 64 ビット・アドレス空間を利用して,新規の 64 ビット・アプリケーションを開発することができます。
すべてが 32 ビット・ポインタ・サイズ(省略時の設定),すべてが 64 ビット・ポインタ・サイズ,および 32 ビットと 64 ビットのポインタ・サイズが混在する環境をそれぞれサポートすることによって, DEC C で 64 ビットの OpenVMS アプリケーションをプログラミングする上で,柔軟性に加えて互換性が提供されます。
32 ビットと 64 ビットのポインタが混在する環境をサポートする ANSI 準拠の #pragma 手法は,Digital UNIX にも共通しています。 64 ビットの C サポート機能には,メモリ割り当てルーチン名のマッピング (_malloc64 および _malloc32 の透過的サポート),および 32 ビットと 64 ビットのポインタ型についての C の型チェックが含まれます。
『OpenVMS Calling Standard』には,ルーチンの起動およびルーチン間でのデータの引き渡しについて,すべての OpenVMS 言語が使用する手法が説明されています。また,エラーおよび例外処理ルーチンにおける一貫性を保持するメカニズムも定義しています。
『OpenVMS Calling Standard』は,常に 64 ビット単位のパラメータを指定しています。 V7.0 より前のリリースの OpenVMS Alpha では,呼び出されたルーチンは,引数の上位 32 ビットを常に無視していました。 OpenVMS Alpha V7.0 以降,『OpenVMS Calling Standard』は,次の 64 ビット・アドレス・サポートを提供します。
混在するポインタのための OpenVMS Alpha の 64 ビット・アドレッシング・サポートには,次の機能も含まれます。
本章は OpenVMS Alpha バージョン 7.0 以降の DEC C ランタイム・ライブラリで提供される 64 ビット・アドレッシング・サポートについて説明します。
DEC C ランタイム・ライブラリは,64 ビット・ポインタをサポートする際に以下の特徴があります。
OpenVMS Alpha バージョン 7.0 以降の DEC C ランタイム・ライブラリは, 64 ビット・ポインタを生成し,受け取ることができます。 64 ビット・ポインタを使用する第 2 のインタフェースを必要とする関数は,対応する 32 ビットと同じオブジェクト・ライブラリおよび共用イメージにあります。オブジェクト・ライブラリや共用イメージが新しく作成されることはありません。 64 ビット・ポインタを使用することで,リンク・コマンドやリンク・オプション・ファイルに変更を加える必要はありません。
DEC C 64 ビット環境を使用すると,1 つのアプリケーションの中で 32 ビット・アドレスと 64 ビット・アドレスの両方を使用できます。ポインタ・サイズの操作についての詳細は,『DEC C User's Guide for OpenVMS Systems』の /POINTER_SIZE 修飾子,および#pragma pointer_sizeまたは#pragma required_pointer_sizeプロセッサ・ディレクティブに関する記述を参照してください。
/POINTER_SIZE 修飾子に対して,ユーザは値 32 または 64 を指定します。ここで指定した値は,コンパイル・ユニットの中の省略時の設定のポインタ・サイズとして使用されます。アプリケーション・プログラマは,あるモジュール・セットは 32 ビット・ポインタを使用して,また別のセットは 64 ビット・ポインタを使用してコンパイルします。この 2 つのモジュール・グループがお互いを呼び出す場合,特に注意しなければなりません。
/POINTER_SIZE 修飾子の使用は,DEC C RTL ヘッダ・ファイルの処理にも影響します。 32 ビット実装および 64 ビット実装を持つ関数の場合,修飾子に指定される実際の値に関わらず,/POINTER SIZE 修飾子によって関数プロトタイプは両方の関数にアクセスできます。さらに,修飾子に指定される値は,コンパイル・ユニットの中で呼び出す省略時の設定の実装を決定します。
#pragma pointer_sizeおよび#pragma required_pointer_sizeプロセッサ・ディレクティブは,コンパイル・ユニットの中で使用されるポインタ・サイズを変更します。 32 ビット・ポインタを省略時の設定のポインタとし,モジュール内の特定のポインタを 64 ビット・ポインタとして宣言することができます。 64 ビット・メモリ領域からメモリを取得するために,mallocの_malloc64形式を呼び出す必要があります。
11.2 メモリを指す 64 ビット・ポインタの取得
DEC C RTL には,新しく割り当てられたメモリへのポインタを返す関数が数多くあります。これらの各関数の中で,アプリケーションは指されているメモリを所有し,そのメモリを解放する責任があります。
メモリを割り当てる関数は次に示します。
malloc
calloc
realloc
strdup
各関数とも 32 ビット実装および 64 ビット実装を持ちます。 /POINTER SIZE 修飾子が使用される場合,次の関数が呼び出される可能性もあります。
_malloc32, _malloc64
_calloc32, _calloc64
_realloc32, _realloc64
_strdup32, _strdup64
/POINTER_SIZE=32 が指定されると,すべてのmalloc呼び出しの省略時の設定は_malloc32になります。
/POINTER_SIZE=64 が指定されると,すべてのmalloc呼び出しの省略時の設定は_malloc64になります。
アプリケーションが 32 ビットまたは 64 ビットのどちらのメモリ割り当てルーチンを呼び出した場合も,free関数があります。この関数はどちらのサイズのポインタも受け取ります。
メモリ割り当て関数は,64 ビット・メモリへのポインタを返す唯一の関数です。 (FILE,WINDOW,DIR などのように)呼び出しアプリケーションに返されるすべての DEC C RTL 構造ポインタは,通常は 32 ビット・ポインタです。このため 32 ビットと 64 ビットの両方の呼び出し側とも,アプリケーションの中でこれらの構造ポインタを渡すことができます。
11.3 DEC C ヘッダ・ファイル
DEC C バージョン 5.2 以降で提供するヘッダ・ファイルは, 64 ビット・ポインタをサポートします。ポインタを含む各関数プロトタイプは,受け取るポインタのサイズを示すように構成されています。
32 ビット・ポインタまたは 64 ビット・ポインタのいずれか 1 つを引数として受け取る関数に対して, 32 ビット・ポインタをその引数として渡すことができます。
しかし,32 ビット・ポインタを受け取る関数への引数として, 64 ビット・ポインタを渡すことはできません。この操作を試みると,コンパイラによって診断が行われ,MAYLOSEDATA メッセージが表示されます。なお,IMPLICITFUNC 診断メッセージが表示された場合,これは,その関数の呼び出しについて,ポインタ・サイズのチェックをこれ以上実行できないことを表します。
特に有効なポインタ・サイズについてのコンパイラの診断メッセージを次に示します。
指定された関数の使用に先立ち,関数プロトタイプが見つからないことを表します。コンパイラおよびランタイム・システムは,プロトタイプ定義に基づいて,不適切なポインタ・サイズの使用を検出します。正しいヘッダ・ファイルがインクルードできないと,不適切な結果が生じたり,ポインタの切り捨てが発生する可能性があります。
この操作を実行するには切り捨てが必要であることを表します。この操作では,指定されたコンテキストの中で 64 ビット・ポインタをサポートしない関数に対して, 64 ビット・ポインタを渡している可能性があります。または関数の戻り値は 64 ビット・ポインタを返し,ソースはその戻り値を 32 ビット・ポインタに保存しようとしている可能性があります。
(有効な場合)このメッセージは,キャスト操作により表示が抑止されている本当の MAYLOSEDATA メッセージを出力することを可能にします。
OpenVMS Alpha バージョン 7.0 が提供する DEC C RTL は, 32 ビット・ポインタだけを使用するアプリケーション, 64 ビット・ポインタだけを使用するアプリケーション,または両方を組み合わせて使用するアプリケーションにそれぞれ適応します。 64 ビット・メモリを使用するには,少なくともアプリケーションの再コンパイルと再リンクが必要です。ソース・コードの変更量は,アプリケーション,ほかのランタイム・ライブラリへの呼び出し,使用されているポインタ・サイズの組み合わせによってそれぞれ異なります。
DEC C RTL 関数は,次の 4 種類に分類できます。
アプリケーション開発者の立場からすると,上記の最初の 2 つの関数は単一ポインタ・モードと混合ポインタ・モードのいずれの場合も簡単に使用できます。
3 番目の関数は,単一ポインタ・モードで使用している場合はソース・コードを変更する必要はありません。ただし混合ポインタ・モードで使用している場合は,ソース・コードの変更が必要です。
4 番目の関数は,64 ビット・ポインタを使用している場合は十分な注意が必要です。
11.4.1 ポインタ・サイズの影響がない関数
プロトタイプにポインタに関連するパラメータや戻り値が含まれていない場合,ポインタ・サイズの選択による関数への影響を考慮する必要はありません。算術関数がこれに相当します。
この種類の関数のうち,プロトタイプにポインタを含まない関数は,ポインタ・サイズの選択による影響はありません。たとえばstrerror関数のプロトタイプは次のとおりです。
char * strerror (int error_number); |
この関数は文字列へのポインタを返しますが,この文字列は DEC C RTL で割り当てられます。その結果,32 ビット・アプリケーションと 64 ビット・アプリケーションを両方ともサポートするために,この種類のポインタは, 32 ビット・ポインタに対応することが常に保証されています。
11.4.2 両方のポインタ・サイズを受け取る関数
Alpha アーキテクチャは 64 ビット・ポインタをサポートします。 OpenVMS Alpha 呼び出し規則では,すべての引数が 64 ビット値として渡されることを指定しています。 OpenVMS Alpha Version 7.0 より前のバージョンでは,プロシージャに渡される 32 ビット・アドレスはすべて, 64 ビット・パラメータに符号拡張されていました。呼び出された関数はパラメータを 32 ビット・アドレスとして宣言し,これによってコンパイラは 32 ビット命令 (LDL など) を生成して,これらのパラメータを処理していました。
DEC C RTL 内の関数の多くは拡張され, 64 ビット・アドレス全体を受け取るようになりました。関数strlenを例に考えます。
size_t strlen (const char *string); |
この関数内の唯一のポインタは文字列ポインタです。ユーザが 32 ビット・ポインタを渡すと,関数は符号拡張された 64 ビット・アドレスで動作します。ユーザが 64 ビット・アドレスを渡すと,関数はそのアドレスで直接動作します。
DEC C RTL は引き続き,この種類の関数に対して, 1 つのエントリ・ポイントだけを持ちます。この種類の関数の 4 つのポインタ・サイズ・オプションのいずれを追加する場合も,ソース・コードの変更は必要ありません。OpenVMS マニュアルでは,これらの関数を 64 ビット・フレンドリと呼びます。
11.4.3 2 種類の実装を持つ関数
多くの理由から,関数は,32 ビット・ポインタ用と 64 ビット・ポインタ用に 2 種類の実装を持つ必要があります。その理由を次に示します。
アプリケーション開発者の立場から見ると,これらの各関数にはそれぞれ 3 種類の関数プロトタイプがあります。<string.h>ヘッダ・ファイルは,その戻り値が先頭引数のポインタ・サイズに依存する多くの関数を持ちます。memset関数を例に考えます。ヘッダ・ファイルは,この関数に対して 3 つのエントリ・ポインタを定義します。
void * memset (void *memory_pointer, int character, size_t size); void *_memset32 (void *memory_pointer, int character, size_t size); void *_memset64 (void *memory_pointer, int character, size_t size); |
最初のプロトタイプは,この関数を使用している場合に,アプリケーションが現在呼び出している関数です。コンパイラはmemsetへの呼び出しを, /POINTER_SIZE=32 でコンパイルされているときは_memset32への呼び出しに,また,/POINTER_SIZE=64 コンパイルされているときは_memset64呼び出しにそれぞれ置換します。
関数の 32 ビット形式または 64 ビット形式を直接呼び出すことにより,この省略時の設定の動作を変更することができます。これにより /POINTER_SIZE 修飾子で指定した省略時の設定のポインタ・サイズに関係なく,ポインタ・サイズが混在しているアプリケーションに対応できます。
/POINTER_SIZE 修飾子を指定せずにコンパイルしている場合, 32 ビット固有のインタフェース関数プロトタイプも, 64 ビット固有のインタフェース関数プロトタイプも定義されないことに注意してください。この場合コンパイラは,2 種類の実装を持つインタフェースに対して,自動的に 32 ビット・インタフェースを呼び出します。
DEC C RTL での 64 ビット・ポインタ・サイズのサポートの一環として, 2 種類の実装を持つ関数の一覧を 表 11-1 に示します。 /POINTER_SIZE 修飾子を指定してコンパイルしている場合,修正されていない関数名を呼び出すと,その修飾子で指定されるポインタ・サイズに対応するインタフェースが呼び出されます。
basename | malloc | strpbrk | wcsncat |
bsearch | mbsrtowcs | strptime | wcsncpy |
calloc | memccpy | strrchr | wcspbrk |
catgets | memchr | strsep | wcsrchr |
ctermid | memcpy | strstr | wcsrtombs |
cuserid | memmove | strtod | wcsstr |
dirname | memset | strtok | wcstok |
fgetname | mktemp | strtol | wcstol |
fgets | mmap | strtoll | wcstoul |
fgetws | qsort | strtoq | wcswcs |
fullname | realloc | strtoul | wmemchr |
gcvt | rindex | strtoull | wmemcpy |
getcap | strcat | strtouq | wmemmove |
getcwd | strchr | tgetstr | wmemset |
getname | strcpy | tmpnam | |
gets | strdup | wcscat | |
index | strncat | wcschr | |
longname | strncpy | wcscpy |
前へ | 次へ | 目次 | 索引 |