日本-日本語 |
|
|
|
OpenVMS マニュアル |
|
HP OpenVMS
|
目次 | 索引 |
プロトタイプにポインタ関連パラメータや戻り値が含まれていない場合は,ポインタ・サイズの選択は関数に影響を与えません。このような関数の例として,算術演算関数があります。
このカテゴリに分類される関数で,プロトタイプにポインタを含む一部の関数もポインタ・サイズの影響を受けません。たとえば, strerrorには,次のプロトタイプがあります。
char * strerror (int error_number); |
この関数は文字列を指すポインタを返しますが,この文字列は HP C RTL によって割り振られます。この結果,32 ビット・アプリケーションと 64 ビット・アプリケーションの両方をサポートするために,これらのポインタ・タイプは 32 ビット・ポインタに収まるように保証されます。
Alpha アーキテクチャでは 64 ビット・ポインタがサポートされます。 OpenVMS Alpha の呼び出し標準規約では,すべての引数は実際に 64 ビットの値として渡されることが指定されています。 OpenVMS Alpha Version 7.0 より前のバージョンでは,プロシージャに渡されるすべての 32 ビット・アドレスは,この 64 ビット・パラメータになるように符号拡張されていました。呼び出される関数は 32 ビット・アドレスとしてパラメータを宣言し,コンパイラはこれらのパラメータを操作するために 32 ビットの命令 (LDL など) を生成していました。
HP C RTL の多くの関数は,完全な 64 ビット・アドレスを受け付けることができるように拡張されています。たとえば,
strlenについて考えてみましょう。
1.9.4.2 両方のポインタ・サイズを受け付ける関数
size_t strlen (const char *string); |
この関数のポインタは文字列ポインタだけです。呼び出し元が 32 ビット・ポインタを渡すと,関数は符号拡張された 64 ビット・アドレスを操作します。呼び出し元が 64 ビット・アドレスを渡した場合は,関数はそのアドレスを直接操作します。
HP C RTL は,このカテゴリに分類される関数に対して,今後もエントリ・ポイントを 1 つだけ使用します。この種の関数に対して 4 種類のポインタ・サイズ・オプションを追加するためにソース・コードを変更する必要はありません。 OpenVMS のドキュメントでは,このような関数を「64 ビットと親和性がある関数」と呼んでいます。
多くの理由から,1 つの関数に対して 32 ビット・ポインタを取り扱う実装と 64 ビット・ポインタを取り扱う実装を用意しなければならないことがあります。たとえば,次のような場合が考えられます。
アプリケーション開発者の立場から考えると,これらの各関数に対して 3 つの関数プロトタイプがあります。
<string.h>ヘッダ・ファイルには,戻り値が関数呼び出しの最初の引数として使用されたポインタ・サイズに依存する多くの関数が含まれています。たとえば,
memset関数について考えてみましょう。ヘッダ・ファイルはこの関数に対して 3 つのエントリ・ポイントを定義しています。
1.9.4.3 2 つの実装のある関数
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); |
最初のプロトタイプは,この関数を使用したときにアプリケーションが現在呼び出している関数です。 /POINTER_SIZE=32 を使用してコンパイルした場合は,コンパイラは memsetに対する呼び出しを _memset32に変更し, /POINTER_SIZE=64 を指定してコンパイルした場合は, _memset64に変更します。
このデフォルトの動作は,関数の 32 ビット形式または 64 ビット形式を直接呼び出すことにより変更できます。この機能は,/POINTER_SIZE 修飾子で指定したデフォルト・ポインタ・サイズとは無関係に,複合ポインタ・サイズを使用するアプリケーションに対応します。
/POINTER_SIZE 修飾子を指定せずにアプリケーションをコンパイルした場合は,32 ビット固有の関数プロトタイプも, 64 ビット固有の関数プロトタイプも定義されません。この場合,コンパイラは 2 種類の実装のあるすべてのインタフェースに対して,自動的に 32 ビット・インタフェースを呼び出します。
表 1-5 は,64 ビット・ポインタ・サイズをサポートするために 2 種類の実装を用意している HP C RTL 関数を示しています。 /POINTER_SIZE 修飾子を使用してコンパイルした場合,変更されていない関数名の呼び出しは,修飾子に指定したポインタ・サイズに対応する関数インタフェースに変更されます。
basename | bsearch | calloc | catgets |
ctermid | cuserid | dirname | fgetname |
fgets | fgetws | gcvt | getcwd |
getname | getpwent | getpwnam | getpwnam_r |
getpwuid | getpwuid_r | gets | index |
longname | malloc | mbsrtowcs | memccpy |
memchr | memcpy | memmove | memset |
mktemp | mmap | qsort | readv |
realloc | rindex | strcat | strchr |
strcpy | strdup | strncat | strncpy |
strpbrk | strptime | strrchr | strsep |
strstr | strtod | strtok | strtok_r |
strtol | strtoll | strtoq | strtoul |
strtoull | strtouq | tmpnam | wcscat |
wcschr | wcscpy | wcsncat | wcsncpy |
wcspbrk | wcsrchr | wcsrtombs | wcsstr |
wcstok | wcstol | wcstoul | wcswcs |
wmemchr | wmemcpy | wmemmove | wmemset |
writev | glob | globfree |
表 1-6 に, 64 ビット・ポインタ・サイズをサポートするために 2 種類の実装が用意されている TCP/IP ソケット・ルーチンを示します。
freeaddrinfo | getaddrinfo |
recvmsg | sendmsg |
OpenVMS Version 8.3 以降,次のソケット・ルーチンで 64 KB を超えるソケットの転送をサポートしています。
1.9.4.4 64 KB を超えるソケットの転送
send | recv | read |
sendto | recvfrom | write |
sendmsg | recvmsg |
getaddrinfo getpwnam freeaddrinfo getpwnam_r getpwuid getpwent sendmsg getpwent_r recvmsg |
これらの関数は,以前はたとえ /POINTER_SIZE=LONG を指定してコンパイルしても 32 ビットのみサポートしていました。 /POINTER_SIZE=LONG でコンパイルした場合もこれらの関数で以前の 32 ビット・ポインタ・サポートの動作を保つようにするため,これらの 7 つの関数は,前の項で説明した 32 ビットと 64 ビットのサポートのための通常の規則には従いません。
これらの関数の次のような変形とそれらが対応する構造体が, 64 ビット・サポートのために C RTL に追加されています。
Function Structure -------- --------- __getaddrinfo32 __addrinfo32 __getaddrinfo64 __addrinfo64 __freeaddrinfo32 __addrinfo32 __freeaddrinfo64 __addrinfo64 __recvmsg32 __msghdr32 __recvmsg64 __msghdr64 __sendmsg32 __msghdr32 __sendmsg64 __msghdr64 __32_getpwnam __passwd32 __64_getpwnam __passwd64 _getpwnam_r32 __passwd32 _getpwnam_r64 __passwd64 __32_getpwuid __passwd32 __64_getpwuid __passwd64 _getpwuid_r32 __passwd32 _getpwuid_r64 __passwd64 __32_getpwent __passwd32 __64_getpwent __passwd64 |
これらの関数の標準バージョンをコンパイルする場合は,次のような動作が発生します。
これらの関数では,対応する構造体に関して同様の変換は行われません。この動作は,これらの構造体が 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-7 は,32 ビット・ポインタに制限される関数を示しています。 HP C RTL では,これらの関数に対して 64 ビットのポインタはサポートされません。これらの関数では 32 ビット・ポインタだけを使用するように注意しなければなりません。
1.9.4.6 32 ビット・ポインタに制限される関数
atexit | getopt | putenv |
execv | iconv | setbuf |
execve | initstate | setstate |
execvp | ioctl | setvbuf |
表 1-8 は,関数呼び出しの処理の一部としてユーザ指定関数に対するコールバックを作成する関数を示しています。コールバック・プロシージャには 64 ビット・ポインタは渡されません。
decc$from_vms | decc$to_vms |
ftw | tputs |
目次 | 索引 |
|