すでに説明したように、32 ビットと 64 ビットの環境の大きな違いは、データ型モデルです。
32 ビットアプリケーションに使用される C データ型モデルは ILP32 で、int
、long
、およびポインタが 32 ビットであるためそのように呼ばれています。LP64 データ型モデルは、64 ビットアプリケーション用の C データ型モデルで、業界の企業コンソーシアムで合意を得ています。この LP64 データ型モデルは、long
とポインタが 64 ビットに拡大されたためそのように呼ばれています。ほかの C データ型 int
、short
、char
は、ILP32 データ型モデルと同じです。
次に示すプログラミング例 foo.c では、LP64 と ILP32 のデータ型モデルの効果を直接的に示しています。同じプログラムを 32 ビットまたは 64 ビットプログラムとしてコンパイルすることができます。
#include <stdio.h> int main(int argc, char *argv[]) { (void) printf("char is \t\t%lu bytes\n", sizeof (char)); (void) printf("short is \t%lu bytes\n", sizeof (short)); (void) printf("int is \t\t%lu bytes\n", sizeof (int)); (void) printf("long is \t\t%lu bytes\n", sizeof (long)); (void) printf("long long is \t\t%lu bytes\n", sizeof (long long)); (void) printf("pointer is \t%lu bytes\n", sizeof (void *)); return (0); }
32 ビットコンパイルの結果は、次のようになります。
% cc -O -o foo32 foo.c % foo32 char is 1 bytes short is 2 bytes int is 4 bytes long is 4 bytes long long is 8 bytes pointer is 4 bytes |
64 ビットコンパイルの結果は、次のようになります。
% cc -xarch=generic64 -O -o foo64 foo.c % foo64 char is 1 bytes short is 2 bytes int is 4 bytes long is 8 bytes long long is 8 bytes pointer is 8 bytes |
デフォルトのコンパイル環境は、移植性を最大限にするように設計されているため、32 ビットのアプリケーションを作成します。
次に示すように C の各整数データ型間の標準的な関係は変わりません。
sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)
表 4–1 に C の基本データ型、およびそれらの LP32 と LP64 のデータ型モデルのビットサイズを示します。
表 4–1 データ型サイズ (単位 : ビット)
C データ型 |
ILP32 |
LP64 |
---|---|---|
|
8 |
変更なし |
|
16 |
変更なし |
|
32 |
変更なし |
|
32 |
64 |
|
64 |
変更なし |
|
32 |
64 |
|
32 |
変更なし |
|
32 |
変更なし |
|
64 |
変更なし |
|
128 |
変更なし |
int
、long
、およびポインタ型を区別なく使用する旧式の 32 ビットアプリケーションもあります。long
とポインタのサイズが LP64 データ型モデルで大きくなっています。この点から、32 ビットから 64 ビットへの多くの変換の問題が発生する可能性があるということを認識する必要があります。
さらに意図するプログラム処理を示すためには、宣言とキャストが重要になります。たとえば、データ型が変わると式の評価方法が影響を受ける可能性があります。データ型のサイズが変更された場合には、C の標準の変換規則は影響を受けます。意図する内容を明確に示すには、定数の型を宣言する必要があります。キャストを式に入れることによって、式を確実に意図するように評価させることも必要です。これは特に、符号拡張の場合に当てはまります。この場合、目的の処理を正しく示すには、明示的にキャストする必要があります。
その他の問題としては、組み込みの C 演算子、書式文字列、アセンブリ言語、互換性、および相互運用性の問題があります。
この章の以降の節で、次のようにこれらの問題の対処方法を紹介します。
これまで概要を示した問題の詳細な説明
コードを 32 ビットおよび 64 ビットに対して安全にするのに有用な、派生型とインクルードファイルの解説
コードを 64 ビット安全にするためのツールの紹介
32 ビットおよび 64 ビット環境間でコードを移植可能にするための一般的規則