日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第 1 章:はじめに
第 2 章:入出力について
第 3 章:文字/文字列/引数リスト関数
第 4 章:エラー処理とシグナル処理
第 5 章:サブプロセス関数
第 6 章:Curses画面管理関数とマクロ
第 7 章:算術関数
第 8 章:メモリ割り当て関数
第 9 章:システム関数
第 10 章:国際化ソフトウェアの開発
第 11 章:日付/時刻関数
第 12 章:シンボリックリンクとPOSIXパス名
付録 A:各OSバージョンでサポートする関数一覧
付録 B:非標準ヘッダに複製されているプロトタイプ
索引
PDF
OpenVMS ホーム

HP OpenVMS
HP C ランタイム・ライブラリ・リファレンス・マニュアル (上巻)


目次 索引



プロトタイプにポインタ関連パラメータや戻り値が含まれていない場合は,ポインタ・サイズの選択は関数に影響を与えません。このような関数の例として,算術演算関数があります。

このカテゴリに分類される関数で,プロトタイプにポインタを含む一部の関数もポインタ・サイズの影響を受けません。たとえば, 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について考えてみましょう。

size_t strlen (const char *string); 

この関数のポインタは文字列ポインタだけです。呼び出し元が 32 ビット・ポインタを渡すと,関数は符号拡張された 64 ビット・アドレスを操作します。呼び出し元が 64 ビット・アドレスを渡した場合は,関数はそのアドレスを直接操作します。

HP C RTL は,このカテゴリに分類される関数に対して,今後もエントリ・ポイントを 1 つだけ使用します。この種の関数に対して 4 種類のポインタ・サイズ・オプションを追加するためにソース・コードを変更する必要はありません。 OpenVMS のドキュメントでは,このような関数を「64 ビットと親和性がある関数」と呼んでいます。

多くの理由から,1 つの関数に対して 32 ビット・ポインタを取り扱う実装と 64 ビット・ポインタを取り扱う実装を用意しなければならないことがあります。たとえば,次のような場合が考えられます。

  • 戻り値のポインタ・サイズが引数のいずれかのポインタ・サイズと同じサイズである場合。たとえば,引数が 32 ビットの場合は,戻り値は 32 ビット,引数が 64 ビットの場合は,戻り値は 64 ビットになります。

  • 引数のいずれかが,ポインタ・サイズに敏感に反応するオブジェクトを指すポインタである場合。指し示すバイト数を知るためには,関数はコードが 32 ビット・ポインタ・サイズ・モードでコンパイルされたのか, 64 ビット・ポインタ・サイズ・モードでコンパイルされたのかを知る必要があります。

  • 関数が動的に割り当てられたメモリのアドレスを返す場合。 32 ビット・ポインタに対してコンパイルされた場合は,メモリは 32 ビット空間に割り当てられ, 64 ビット・ポインタに対してコンパイルされた場合は, 64 ビット空間に割り当てられます。

アプリケーション開発者の立場から考えると,これらの各関数に対して 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); 

最初のプロトタイプは,この関数を使用したときにアプリケーションが現在呼び出している関数です。 /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 修飾子を使用してコンパイルした場合,変更されていない関数名の呼び出しは,修飾子に指定したポインタ・サイズに対応する関数インタフェースに変更されます。

表 1-5 2 種類の実装が用意されている関数
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 ソケット・ルーチンを示します。

表 1-6 2 種類の実装が用意されているソケット・ルーチン
freeaddrinfo getaddrinfo
recvmsg sendmsg



OpenVMS Version 8.3 以降,次のソケット・ルーチンで 64 KB を超えるソケットの転送をサポートしています。

send recv read
sendto recvfrom write
sendmsg recvmsg  



いくつかの関数では,/POINTER_SIZE=LONG でコンパイルする際に,明示的に 64 ビット構造体を使用する必要があります。最近 64 ビット・サポートが追加された関数では,不注意により 32 ビット版の構造体と 64 ビット版の構造体が混在した場合に,予期しない実行時エラーが起こるのを防ぐためにこのようにする必要があります。

次のような関数について考えて見ましょう。

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 

これらの関数の標準バージョンをコンパイルする場合は,次のような動作が発生します。

  • /POINTER_SIZE=32 を指定すると,コンパイラは, 32 ビット・バージョンの関数呼び出しに変換します。たとえば, getaddrinfo__getaddrinfo32に変換されます。

  • /POINTER_SIZE=64 を指定すると,コンパイラは, 64 ビット・バージョンの関数呼び出しに変換します。たとえば, getaddrinfo__getaddrinfo64に変換されます。

  • /POINTER_SIZE 修飾子を指定しなかった場合, 32 ビット固有関数プロトタイプも 64 ビット固有関数プロトタイプも定義されません。

これらの関数では,対応する構造体に関して同様の変換は行われません。この動作は,これらの構造体が 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-7 32 ビット・ポインタに制限される関数
atexit getopt putenv
execv iconv setbuf
execve initstate setstate
execvp ioctl setvbuf

表 1-8 は,関数呼び出しの処理の一部としてユーザ指定関数に対するコールバックを作成する関数を示しています。コールバック・プロシージャには 64 ビット・ポインタは渡されません。

表 1-8 32 ビット・ポインタのみを渡すコールバック
decc$from_vms decc$to_vms
ftw tputs


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.