JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.3: C ユーザーガイド     Oracle Solaris Studio 12.3 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

1.  C コンパイラの紹介

2.  C コンパイラ実装に固有の情報

3.  C コードの並列化

4.  lint ソースコード検査プログラム

5.  型に基づく別名解析

6.  ISO C への移行

7.  64 ビット環境に対応するアプリケーションへの変換

7.1 データ型モデルの相違点

7.2 単一ソースコードの実現

7.2.1 派生型

7.2.1.1 <sys/types.h>

7.2.1.2 <inttypes.h>

固定幅の整数型

unintptr_t などの便利な型

定数マクロ

制限

書式文字列マクロ

7.2.2 lint によるチェック

7.3 LP64 データ型モデルへの変換

7.3.1 整数とポインタのサイズの変更

7.3.2 整数とロング整数のサイズの変更

7.3.3 符号拡張

7.3.4 整数の代わりのポインタ演算

7.3.5 構造体

7.3.6 共用体

7.3.7 型定数

7.3.8 暗黙の宣言に対する注意

7.3.9 sizeof( ) は符号なし long

7.3.10 型変換で意図を明確にする

7.3.11 書式文字列の変換操作を検査する

7.4 変換に関するその他の注意事項

7.4.1 注: サイズが大きくなった派生型

7.4.2 変更の副作用の検査

7.4.3 long のリテラル使用の効果持続の確認

7.4.4 明示的な 32 ビットと 64 ビットプロトタイプに対する #ifdef の使用

7.4.5 呼び出し規則の変更

7.4.6 アルゴリズムの変更

7.5 変換前の確認事項

8.  cscope: 対話的な C プログラムの検査

A.  機能別コンパイラオプション

B.  C コンパイラオプションリファレンス

C.  ISO/IEC C 99 の処理系定義の動作

D.  C99 の機能

E.  ISO/IEC C90 の処理系定義の動作

F.  ISO C データ表現

G.  パフォーマンスチューニング

H.  Oracle Solaris Studio C: K&R C と ISO C の違い

索引

7.2 単一ソースコードの実現

この節では、32 ビットと 64 ビットの両方でコンパイル可能な単一ソースコードの作成に使用できる資源をいくつか紹介します。

7.2.1 派生型

32 ビットと 64 ビットの両方のコンパイル環境でコードを安全にするためにシステム派生型を使用することは、良いプログラミング方法です。派生データ型を使用するときに、データ型モデルの変更または移植のためにはシステム派生型だけを変更する必要があります。

システムインクルードファイルの <sys/types.h> および <inttypes.h> には、32 ビットと 64 ビットのどちらにも安全なアプリケーションの作成に役立つ定数、マクロ、派生型が含まれています。

7.2.1.1 <sys/types.h>

アプリケーションのソースファイルに <sys/types.h> をインクルードして、_LP64 および _ILP32 の定義を使用できるようにしてください。このヘッダーには、必要に応じて使用される基本派生型もいくつか含まれています。特に次は大切です。

これらの派生型はすべて、ILP32 コンパイル環境では 32 ビット量のままですが、LP64 コンパイル環境では、64 ビット量になります。

7.2.1.2 <inttypes.h>

<inttypes.h> インクルードファイルには、コンパイル環境に関係なく、明示的にサイズ指定されたデータ項目との互換性を持たせるのに役立つ定数、マクロ、派生型が含まれています。このファイルには、8、16、32、64 ビットオブジェクトを操作するための仕組みも含まれています。<inttypes.h> に含まれることが議論されている基本機能としては、次のものがあります。

次に <inttypes.h> のこれらの基本機能について詳しく説明します。

固定幅の整数型

<inttypes.h> が提供する固定幅の整数型には、int8_tint16_tint32_tint64_t などの符号付整数型と、uint8_tuint16_tuint32_tuint64_t などの符号なし整数型が含まれます。

指定数のビットを保持できる最小サイズの整数型として定義されている派生型には、int_least8_t、…、int_least64_tuint_least8_t、…、uint_least64_t が含まれます。

ループカウンタやファイル記述子などの演算に int または unsigned int を使用することは安全です。配列インデックスに long を使用することも安全です。しかし、これらの固定幅型はむやみに使用しないでください。固定幅の型は、次の項目の明示的なバイナリ表現に使用してください。

unintptr_t などの便利な型

<inttypes.h> ファイルには、ポインタを保持するのに十分な大きさの符号付き整数型と符号なし整数型 intptr_tuintptr_t が含まれます。また、<inttypes.h> は符号付きと符号なし整数型の中で最長 (ビット) の整数型である intmax_tuintmax_t も提供します。

uintptr_t 型は、unsigned long などの基本型ではなく、ポインタ用の整数型として使用してください。ILP32 と LP64 の両方のデータ型モデルで unsigned long がポインタと同じサイズであるとしても、uintptr_t を使用することは、データ型モデルが変わった場合に、uintptr_t の定義だけが影響を受けることを意味します。この方法は、コードをほかの多くのシステムに移植可能にし、意図を C で表現するためのより明確な方法でもあります。

intptr_t および uintptr_t 型は、アドレス演算でポインタの型変換を行うときに大変役立ちます。この目的には、long や符号なし long ではなく、intptr_tuintptr_t 型を使用してください。

定数マクロ

定数のサイズと符号の指定には、INT8_C(c)INT64_C(c)UINT8_C(c)UINT64_C(c) マクロを使用してください。基本的に、これらのマクロは、必要に応じて定数の末尾に lulllull という文字列を追加します。たとえば、INT64_C(1) は、ILP32 では、定数 1 に ll、LP 64 では l を付加します。

定数を最大型にするときは、INTMAX_C(c)UINTMAX_C(c) を使用してください。これらのマクロは、「7.3 LP64 データ型モデルへの変換」で説明している定数型を指定する際に大変役立ちます。

制限

<inttypes.h> で定義されている上下制限は、いろいろな整数型の最小値と最大値を指示する定数です。これらの制限には、INT8_MININT64_MININT8_MAXINT64_MAX などの各固定幅型とそれらに対応する符合なし型に対する、最小値と最大値が含まれます。

<inttypes.h> ファイルは、最小サイズのそれぞれの型に対する最小値と最大値も提供します。これらの型には、INT_LEAST8_MININT_LEAST64_MININT_LEAST8_MAXINT_LEAST64_MAX 型やそれらに対応する符号なし型が含まれます。

最後に、<inttypes.h> は、サポートされる最大整数型の最小値と最大値を定義します。これらの型には、INTMAX_MININTMAX_MAX、およびそれらに対応する符号なし型が含まれます。

書式文字列マクロ

<inttypes.h> ファイルには printf(3S) および scanf(3S) 書式指示子を指定するマクロが含まれています。基本的にこれらのマクロは、引数のビット数がマクロ名に組み込まれていることを条件に、書式指示子の前に l または ll を付加して、引数が long または long long のどちらであるかを示します。

次の例で示すように、printf(3S) 用の一部のマクロは、最小整数型と最大整数型の両方を 10 進、8 進、符号なし、および 16 進の形式で出力します。

int64_t i;
printf("i =%" PRIx64 "\n", i);

同様に、scanf(3S) 用のマクロは、最小整数型と最大整数型の両方を 10 進、8 進、符号なし、および 16 進の形式で読み取ります。

uint64_t u;
scanf("%" SCNu64 "\n", &u);

これらのマクロはむやみに使用しないでください。「固定幅の整数型」で説明しているように、固定幅型に対して使用するのがもっとも適しています。

7.2.2 lint によるチェック

lint プログラムの -errchk オプションは、64 ビットへの移植でエラーになる可能性のある問題を検出します。cc -v を指定して、より厳密な追加の意味検査を行うようコンパイラに指示することもできます。-v オプションは、指定されたファイルに対してある種 lint に似た検査も有効にします。

コードを拡張して 64 ビット対応にするときは、Oracle Solaris オペレーティングシステムに存在するヘッダーファイルを使用してください。これらのファイルが、64 ビットコンパイル環境用の派生型とデータ構造体の正しい定義を持っているためです。

32 ビットおよび 64 ビットの両方のコンパイル環境用に作成したコードの検査には、lint を使用してください。LP64 の警告を生成するには、-errchk=longptr64 オプションを使用します。また、ロング整数とポインタのサイズが 64 ビットで普通の整数のサイズが 32 ビットの環境への移植性を検査する場合も -errchk=longptr64 フラグを使用してください。-errchk=longptr64 フラグは、明示的な型変換が使用されているときにも、ポインタ式とロング整数式の普通の整数への代入を検査します。

符号なし整数型の式における符号付き整数値の符号拡張を ISO C の通常の値保持規則が認めるコードを検索するには、-errchk=longptr64,signext オプションを使用してください。

Oracle Solaris の 64 ビットコンパイル環境でだけ実行することを意図するコードを検査するときは、lint-m64 オプションを使用してください。

lint の警告は、問題のコードの行番号、問題について説明するメッセージ、ポインタが関係しているかどうかの兆候を示します。また、関係するデータ型のサイズも示します。ポインタが関係していること、データ型のサイズがわかれば、64 ビットの問題を特定し、32 ビットとそれより小さい型の間に以前から存在している問題を避けることできます。

ただし、64 ビット環境でエラーになる可能性のある問題について警告を出すといっても、lint によってすべての問題が検出できるわけではありません。多くの場合、意図したとおりであり、正しいコードであっても、警告は出されます。

行の前に “NOTE(LINTED(“<optional message”>))” の形式のコメントを挿入すると、特定の行に対する警告を抑止できます。このコメント指令は、キャストや代入などの特定のコード行を lint に無視させるときに役立ちます。ただし、現実には存在する問題が隠される可能性があるため、“NOTE(LINTED(“<optional message”>))” コメントを使用するときは、細心の注意を払ってください。NOTE を使用する場合、#include<note.h> のようにして note.h をインクルードしてください。詳細は、lint のマニュアルページを参照してください。