前へ | 次へ | 目次 | 索引 |
これらの関数では,対応する構造体に関して同様の変換は行われません。この動作は,これらの構造体が OpenVMS Version 7.3-2 までは /POINTER_SIZE=LONG でコンパイルした場合も 32 ビット・バージョンとしてのみ存在していたために必要となります。構造体のサイズを変更すると,予測できない実行時エラーが発生することになります。
これらの関数の標準バージョンを使用するプログラムを64 ビット・サポートのためにコンパイルする場合,関連する構造体の64 ビット固有定義を使用する必要があります。標準の関数名および標準の構造体定義を使用するプログラムを /POINTER_SIZE=64 を指定してコンパイルすると,コンパイラ PTRMISMATCH 警告メッセージが発生します。
たとえば次のプログラムは, addrinfo構造体の標準の定義とともに getaddrinfoおよび freeaddrinfoルーチンを使用しています。このプログラムをコンパイルすると,次のような警告メッセージが表示されます。
$ type test.c #include <netdb.h> int main () { struct addrinfo *ai; getaddrinfo ("althea", 0, 0, &ai); freeaddrinfo (ai); return 0; } $ cc /pointer_size=64 TEST.C getaddrinfo ("althea", 0, 0, &ai); ....^ %CC-W-PTRMISMATCH, In this statement, the referenced type of the pointer value "&ai" is "long pointer to struct addrinfo", which is not compatible with "long pointer to struct __addrinfo64". at line number 7 in file TEST.C;1 freeaddrinfo (ai); ....^ %CC-W-PTRMISMATCH, In this statement, the referenced type of the pointer value "ai" is "struct addrinfo", which is not compatible with "struct __addrinfo64". at line number 8 in file TEST.C;1 $ |
64 ビット用にコンパイルする場合は, 64 ビット固有バージョンの構造体を使用する必要があります。前の例の ai構造体の宣言を次のように変更します。
struct __addrinfo64 *ai; |
あるいは,32 ビットと 64 ビットで柔軟にコンパイルできるようにするために,次のように ai構造体を宣言します。
#if __INITIAL_POINTER_SIZE == 64 struct __addrinfo64 *ai; #else struct __addrinfo32 *ai; #endif |
HP C RTL の中の若干の関数は 64 ビット・ポインタをサポートしません。これらの関数に 64 ビット・ポインタを渡そうとすると,コンパイラは %CC-W-MAYLOSEDATA 警告を生成します。 /POINTER_SIZE=64 を指定してコンパイルしたアプリケーションでは, 64 ビット・ポインタをこれらの関数に渡さないように変更する必要があります。
表 1-8 は,32 ビット・ポインタに制限される関数を示しています。 HP C RTL では,これらの関数に対して 64 ビットのポインタはサポートされません。これらの関数では 32 ビット・ポインタだけを使用するように注意しなければなりません。
atexit | frexp | ioctl | setbuf |
execv | getopt | modf | setstate |
execve | iconv | putenv | setvbuf |
execvp | initstate |
表 1-9 は,関数呼び出しの処理の一部としてユーザ指定関数に対するコールバックを作成する関数を示しています。コールバック・プロシージャには 64 ビット・ポインタは渡されません。
decc$from_vms | decc$to_vms |
ftw | tputs |
ここでは, HP C RTL ヘッダ・ファイルで使用されるポインタ・サイズの操作について説明します。これらのヘッダ・ファイルの読み込みについてより理解を深め,各自のヘッダ・ファイルを変更するのに役立つように,次の例を使って説明します。
#1 |
---|
: #if __INITIAL_POINTER_SIZE (1) # if (__VMS_VER < 70000000) || !defined __ALPHA (2) # error " Pointer size usage not permitted before OpenVMS Alpha V7.0" # endif # pragma __pointer_size __save (3) # pragma __pointer_size 32 (4) #endif : : #if __INITIAL_POINTER_SIZE (5) # pragma __pointer_size 64 #endif : : #if __INITIAL_POINTER_SIZE (6) # pragma __pointer_size __restore #endif : |
/POINTER_SIZE 修飾子をサポートするすべての HP C コンパイラでは, __INITIAL_POINTER_SIZEマクロがあらかじめ定義されています。 HP C RTL ヘッダ・ファイルは,マクロが定義されていない場合,暗黙の値として 0 を使用するという ANSI の規則に従います。
/POINTER_SIZE 修飾子が使用された場合は,マクロは 32 または 64 として定義されます。修飾子が使用されない場合は,マクロは 0 として定義されます。 (1) に指定されている文は,「ユーザが /POINTER_SIZE=32 または /POINTER_SIZE=64 をコマンド・ラインに指定した場合」と考えることができます。
OpenVMS の多くのバージョンでは, C コンパイラがサポートされます。 (2) に示した行は,コンパイラの対象が 64 ビット・ポインタをサポートしないプラットフォームの場合,エラー・メッセージを生成します。
ヘッダ・ファイルでは,ヘッダ・ファイルが取り込まれたときに有効な実際のポインタ・サイズ・コンテキストに関して,何も仮定することができません。さらに, HP C コンパイラでは, __INITIAL_POINTER_SIZEマクロとポインタ・サイズを変更するための機能だけが提供され,現在のポインタ・サイズを判断するための方法は提供されません。
ポインタ・サイズに依存するすべてのヘッダ・ファイルは,ポインタ・サイズ・コンテキストの保存 (3),初期化 (4),変更 (5),復元 (6) を行う責任があります。
#2 |
---|
: #ifndef __CHAR_PTR32 (1) # define __CHAR_PTR32 1 typedef char * __char_ptr32; typedef const char * __const_char_ptr32; #endif : : #if __INITIAL_POINTER_SIZE # pragma __pointer_size 64 #endif : : #ifndef __CHAR_PTR64 (2) # define __CHAR_PTR64 1 typedef char * __char_ptr64; typedef const char * __const_char_ptr64; #endif : |
一部の関数プロトタイプでは, 64 ビット・ポインタ・サイズ・コンテキストで 32 ビット・ポインタを参照しなければなりません。また,32 ビット・ポインタ・サイズ・コンテキストで 64 ビット・ポインタを参照しなければならない関数プロトタイプもあります。
HP C は, typedefが作成されるときに, typedefで使用されるポインタ・サイズをバインドします。 __char_ptr32の typedef宣言 (1) は, 32 ビット・コンテキストで行われます。 __char_ptr64の typedef宣言 (2) は 64 ビット・コンテキストで行われます。
#3 |
---|
: #if __INITIAL_POINTER_SIZE # if (__VMS_VER < 70000000) || !defined __ALPHA # error " Pointer size usage not permitted before OpenVMS Alpha V7.0" # endif # pragma __pointer_size __save # pragma __pointer_size 32 #endif : (1) : #if __INITIAL_POINTER_SIZE (2) # pragma __pointer_size 64 #endif : (3) : int abs (int __j); (4) : __char_ptr32 strerror (int __errnum); (5) : |
64 ビット・ポインタをサポートする関数プロトタイプを宣言する前に,ポインタ・コンテキストは 32 ビット・ポインタから 64 ビット・ポインタに変更されます (2)。
32ビット・ポインタに制限される関数は,ヘッダ・ファイルの 32 ビット・ポインタ・コンテキスト・セクション (1) に配置されます。他のすべての関数は,ヘッダ・ファイルの 64 ビット・コンテキスト・セクション (3) に配置されます。
ポインタ・サイズの影響を受けない関数 ((4) と (5)) は 64 ビット・セクションに配置されます。 32 ビットのアドレス戻り値以外はポインタ・サイズの影響を受けない関数 (5) も 64 ビット・セクションに配置され,前に説明したように, 32 ビット固有の typedefを使用します。
#4 |
---|
: #if __INITIAL_POINTER_SIZE # pragma __pointer_size 64 #endif : : #if __INITIAL_POINTER_SIZE == 32 (1) # pragma __pointer_size 32 #endif : char *strcat (char *__s1, __const_char_ptr64 __s2); (2) : #if __INITIAL_POINTER_SIZE # pragma __pointer_size 32 : char *_strcat32 (char *__s1, __const_char_ptr64 __s2); (3) : # pragma __pointer_size 64 : char *_strcat64 (char *__s1, const char *__s2); (4) : #endif : |
この例では, 32 ビット・インプリメンテーションと 64 ビット・インプリメンテーションの両方が用意されている関数の宣言を示しています。これらの宣言はヘッダ・ファイルの 64 ビット・セクションに配置されます。
関数に対する通常のインタフェース (2) は, /POINTER_SIZE 修飾子に指定したポインタ・サイズを使用して宣言されます。ヘッダ・ファイルは 64 ビット・ポインタ・コンテキストに配置され, (1) に示した文が指定されているため, (2) の宣言は,/POINTER_SIZE 修飾子と同じポインタ・サイズ・コンテキストを使用して行われます。
32 ビット固有のインタフェース (3) は 32 ビット・ポインタ・サイズ・コンテキストで宣言され, 64 ビット固有のインタフェース (4) は 64 ビット・ポインタ・サイズ・コンテキストで宣言されます。
HP C Run-Time Library (RTL) には,3 種類の入出力 (I/O) があります。それは UNIX I/O,標準 I/O,端末 I/Oです。 表 2-1 は, HP C RTL のすべての I/O 関数とマクロを示しています。各関数とマクロの詳細については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)』「リファレンス・セクション」を参照してください。
関数またはマクロ | 説明 |
---|---|
UNIX I/O---ファイルのオープンとクローズ | |
close | ファイル記述子に関連付けられているファイルをクローズする。 |
creat | ファイルを新規作成する。 |
dup, dup2 | open , creat , pipe から返されたファイル記述子によって指定されるファイルに新しい記述子を割り当てる。 |
open | ファイルをオープンし,ファイルの位置をファイルの先頭に設定する。 |
UNIX I/O---ファイルからの読み込み | |
read | ファイルからバイトを読み込み,バッファに格納する。 |
UNIX I/O---ファイルへの書き込み | |
write | 指定されたバイト数をバッファからファイルに書き込む。 |
UNIX I/O---ファイル内の位置設定 | |
lseek | ストリーム・ファイルを任意のバイト位置に設定し,新しい位置を int として返す。 |
UNIX I/O---追加の標準 I/O 関数とマクロ | |
fstat, stat | ファイル記述子またはファイル指定に関する情報にアクセスする。 |
fsync | 指定されたファイルに保存するためにバッファに格納されている情報をディスクに書き込む。 |
getname | ファイル記述子に関連付けられているファイル指定を返す。 |
isapipe | ファイル記述子がパイプに関連付けられている場合は 1,関連付けられていない場合は 0 を返す。 |
isatty | 指定されたファイル記述子が端末に関連付けられている場合は 1,関連付けられていない場合は 0 を返す。 |
lwait | 保留中の非同期 I/O の終了を待つ。 |
ttyname | ファイル記述子 0 (デフォルトの入力デバイス) に関連付けられている端末デバイスの名前 (ヌル区切り) を指すポインタを返す。 |
標準 I/O---ファイルのオープンとクローズ | |
fclose | ファイル制御ブロックに関連付けられているバッファの内容を書き込み,ファイル・ポインタに関連付けられているファイル制御ブロックおよびバッファを解放することにより,ファイルをクローズする。 |
fdopen | open , creat , dup , dup2 , pipe 関数から返されたファイル記述子にファイル・ポインタを関連付ける。 |
fopen | FILE 構造体のアドレスを返すことにより,ファイルをオープンする。 (ファイルをオープンしてファイル・ポインタを返す。) |
freopen | ファイル指定によって名前が指定されるファイルを,ファイル・ポインタによってアドレスが指定されるオープンされているファイルに置き換える。 (ファイルをオープンして指定されたファイル・ポインタに結びつける。) |
標準 I/O---ファイルからの読み込み | |
fgetc, getc, fgetwc, getw, getwc | 指定されたファイルから文字を 1 文字読み込む。 |
fgets, fgetws | 指定されたファイルから 1 行を読み込み,文字列を引数に格納する。 |
fread | 指定された数の項目をファイルから読み込む。 |
fscanf, fwscanf, vfscanf, vfwscanf | 指定されたファイルから書式に従って読み込む。 |
sscanf, swscanf, vsscanf, vswscanf | メモリ内の文字列から書式に従って読み込む。 |
ungetc, ungetwc | 文字を入力ストリームに戻し,挿入した文字の前にあるストリームはそのまま残す。 |
標準 I/O---ファイルへの書き込み | |
fprintf, fwprintf, vfprintf, vfwprintf | 指定されたファイルに書式に従って出力する。 |
fputc, putc, putw, putwc, fputwc | 指定されたファイルに文字を書き込む。 |
fputs, fputws | 文字列をファイルに書き込む ( ヌル文字は含まない )。 |
fwrite | 指定された数の項目をファイルに書き込む。 |
sprintf, swprintf, vsprintf, vswprintf | メモリ内の文字列に書式設定された出力を実行する。 |
標準 I/O---ファイル内の位置設定 | |
fflush | 指定されたファイルに保存するためにバッファに格納されている情報を RMS に送信する。 |
fgetpos | ストリームのファイル位置指示子の現在の値を格納する。 |
fsetpos | ポインタが指しているオブジェクトの値に従って,ストリームのファイル位置指示子を設定する。 |
fseek , fseeko | ファイルの位置をファイル内の指定されたバイト・オフセットに設定する。 |
ftell , ftello | 指定されたストリーム・ファイルに対する現在のバイト・オフセットを返す。 |
rewind | ファイルの位置を先頭に設定する。 |
標準 I/O---追加の標準 I/O 関数とマクロ | |
access | ファイルを調べて,指定されたアクセス・モードが許可されているかどうかを確認する。 |
clearerr | ファイルに対するエラー指示子およびファイルの終端 (EOF) 指示子をリセットする。 |
feof | ファイルを調べて,ファイルの終端 (EOF) に到達したかどうかを確認する。 |
ferror | ファイルへの書き込みまたは読み込みでエラーが発生した場合,0 以外の整数を返す。 |
fgetname | ファイル・ポインタに関連付けられているファイル指定を返す。 |
fileno | 指定されたファイルを識別する整数のファイル記述子を返す。 |
ftruncate | ファイルを指定された位置で切り捨てる。 |
fwait | 保留中の非同期 I/O の終了を待つ。 |
fwide | ストリームの単位を設定する。 |
mktemp | テンプレートから固有の名前を作成する。 |
remove, delete | ファイルを削除する。 |
rename | 既存のファイルに新しい名前を付ける。 |
setbuf, setvbuf | バッファを入力ファイルまたは出力ファイルに関連付ける。 |
tmpfile | 一時ファイルを作成して更新のためにオープンする。 |
tmpnam | 他の関数呼び出しでファイル名引数の代わりに使用できる文字列を作成する。 |
端末 I/O---ファイルからの読み込み | |
getchar, getwchar | 標準入力 ( stdin ) から 1 文字を読み込む。 |
gets | 標準入力 ( stdin ) から 1 行を読み込む。 |
scanf, wscanf, vscanf, vwscanf | 標準入力から書式設定された入力を実行する。 |
端末 I/O---ファイルへの書き込み | |
printf, wprintf, vprintf, vwprintf | 標準出力 ( stdout ) に書式設定された出力を実行する。 |
putchar, putwchar | 標準出力に 1 文字を書き込み,その文字を返す。 |
puts | 標準出力に文字列と改行文字を書き込む。 |
前へ | 次へ | 目次 | 索引 |