4.1.3 データの内部表現と領域

この項では,CC-RLが扱うデータのそれぞれの型における,内部表現と値域について説明します。

(1)

整数型

(a)

内部表現

領域の左端ビットは,符号付きの型では,符号ビットとなります。符号付きの型において,値は2の補数表現で表されます。

図 4.1

整数型の内部表現

 

_Bool

ゼロビット目のみが意味を持ちます。1〜7ビット目は不定値となります。

オプション-lang=cかつ-strict_std使用時は,_Bool型はC90違反でエラーとなります。

 

char

signed もunsigned もつかない単なるchar 型は,unsigned char と同じ表現とします。

ただし,オプション-signed_char 使用時は,signed char と同じ表現とします。

 

signed char(unsignedでは符号ビットなし)

 

short(unsignedでは符号ビットなし)

 

int(unsignedでは符号ビットなし)

 

long(unsignedでは符号ビットなし)

 

long long(unsignedでは符号ビットなし)

オプション-lang=cかつ-strict_std使用時は,long long型はC90違反でエラーとなります。

 

(b)

値域

表 4.3

整数型の値域

値域

_Bool

0〜1

signed char

-128〜+127

signed short

-32768〜+32767

signed int

-32768〜+32767

signed long

-2147483648〜+2147483647

signed long long

-9223372036854775808〜+9223372036854775807

(unsigned) char

0〜255

unsigned short

0〜65535

unsigned int

0〜65535

unsigned long

0〜4294967295

unsigned long long

0〜18446744073709551615

(c)

整数定数

整数定数の型は,次の並びのうちでその値を表現できる最初の型となります。

表 4.4

整数定数の型(long long型が有効な場合(-lang=c指定あり,-strict_std指定なし))

接尾語

10進定数

2進定数,8進定数,

または16進定数

なし

int

long int

unsigned long int

long long int

unsigned long long int

int

unsigned int

long int

unsigned long int

long long int

unsigned long long int

u,またはU

unsigned int

unsigned long int

unsigned long long int

unsigned int

unsigned long int

unsigned long long int

l,またはL

long int

unsigned long int

long long int

unsigned long long int

long int

unsigned long int

long long int

unsigned long long int

u,またはU,およびl ,またはL の両方

unsigned long int

unsigned long long int

unsigned long int

unsigned long long int

ll,またはLL

long long int

unsigned long long int

long long int

unsigned long long int

u,またはU,およびll ,またはLLの両方

unsigned long long int

unsigned long long int

C99の仕様と異なります。これはC90 であれば4 バイト・データであるところを,8 バイト・データになることを回避するためです。

表 4.5

整数定数の型(long long型が無効な場合(-lang=c指定あり,-strict_std指定あり))

接尾語

10進定数

2進定数,8進定数,

または16進定数

なし

int

long int

unsigned long int

int

unsigned int

long int

unsigned long int

u,またはU

unsigned int

unsigned long int

unsigned int

unsigned long int

l,またはL

long int

unsigned long int

long int

unsigned long int

u,またはU,およびl ,またはL の両方

unsigned long int

unsigned long int

表 4.6

整数定数の型(long long型が有効な場合(-lang=c99指定あり))

接尾語

10進定数

2進定数,8進定数,

または16進定数

なし

int

long int

long long int

unsigned long long int

int

unsigned int

long int

unsigned long int

long long int

unsigned long long int

u,またはU

unsigned int

unsigned long int

unsigned long long int

unsigned int

unsigned long int

unsigned long long int

l,またはL

long int

long long int

unsigned long long int

long int

unsigned long int

long long int

unsigned long long int

u,またはU,およびl ,またはL の両方

unsigned long int

unsigned long long int

unsigned long int

unsigned long long int

ll,またはLL

long long int

unsigned long long int

long long int

unsigned long long int

u,またはU,およびll ,またはLL の両方

unsigned long long int

unsigned long long int

(2)

浮動小数点型

(a)

内部表現

浮動小数点型データの内部表現は,IEC 60559:1989 (IEEE 754-1985)に準拠しています。領域の左端のビットは,符号ビットとなります。この符号ビットの値が0であれば正の値に,1であれば負の値になります。

IEEE:Institute of Electrical and Electronics Engineers(電気電信学会)の略称です。
また,IEEE754とは,浮動小数点演算を扱うシステムにおいて,扱うデータ形式や数値範囲などの仕様の統一化を図った標準です。

図 4.2

浮動小数点型の内部表現

 

float

S: 仮数部の符号ビット

E: 指数部(8ビット)

M: 仮数部(23ビット)

 

double, long double

S: 仮数部の符号ビット

E: 指数部(11ビット)

M: 仮数部(52ビット)

 

オプション-dbl_size=4使用時はfloat型と同じ表現とします。double型を書いてもfloat型を書いたものとして扱います。long double型も同様にfloat型を書いたものとして扱います。

オプション-dbl_size=8使用時は,64ビットで表現されます。

 

(b)

値域

表 4.7

浮動小数点型の値域

値域

float

1.17549435E-38F〜3.40282347E+38F

double

2.2250738585072014E-308〜1.7976931348623158E+308

long double

2.2250738585072014E-308〜1.7976931348623158E+308

(3)

ポインタ型

(a)

内部表現

nearポインタの内部表現は16ビットの符号なし型,farポインタの内部表現は32ビットの符号なし型となります。

farポインタの最上位1バイトは不定値となります。

空ポインタ定数(NULL)の内部表現は値0となります(ただし,farポインタの不定値部分は0とは限りません)。

このため,near ポインタ,far ポインタ共にゼロ番地に対するアクセスは保証しません。

farポインタの値が0xfffffを越えた場合の動作は保証しません。

0x0f0000番地に関数や変数を配置したり,アクセスすることはしないでください。

図 4.3

ポインタ型の内部表現

 

nearポインタ

 

farポインタ

 

(4)

列挙型

(a)

内部表現

列挙型の内部表現は,列挙子の値の範囲によって変化します。

<1>

オプション-signed_charなし

列挙子の下限値

列挙子の上限値

内部表現の型

備考

-128

127

signed char

 

0

255

char

0〜127 の場合はここに含む

上記以外

signed short

 

<2>

オプション-signed_charあり

列挙子の下限値

列挙子の上限値

内部表現の型

備考

-128

127

char

0〜127 の場合はここに含む

0

255

unsigned char

 

上記以外

signed short

 

(5)

配列型

(a)

内部表現

配列型の内部表現は,配列の要素を,その要素の整列条件(alignment)を満たす形で並べたものとなります。

char    a[8] = {1, 2, 3, 4, 5, 6, 7, 8};

 

上記の例に示した配列に対する内部表現は,次のようになります。

図 4.4

配列型の内部表現

 

(6)

構造体型

(a)

内部表現

ひとつの構造体において,各メンバは構造体先頭から宣言順に配置されます。構造体型の内部表現は,構造体の要素をその要素の整列条件を満たす形で並べたものとなります。

構造体全体の整列条件は,その構造体で最も大きなメンバの整列条件に合わせたものとなります。このルールは,メンバが構造体や共用体の場合にも再帰的に適用されます。

構造体のサイズは「構造体全体の整列条件」の倍数となります。したがって,構造体の末尾が構造体自身の整列条件とあわない場合に次の整列条件を保証するために作成される未使用領域もサイズに含まれます。

例 1.

struct {
        short           s1;
        signed long     s2;
        char            s3;
        signed long     s4;
} s;

 

この例に示した構造体に対する内部表現は,次のようになります。

図 4.5

構造体型の内部表現(構造体パッキング指定なし)

図 4.6

構造体型の内部表現(構造体パッキング指定あり)

 

例 2.

struct {
        short           s1;
        char            s2;
} s;

 

この例に示した構造体に対する内部表現は,次のようになります。

図 4.7

構造体型の内部表現(構造体パッキング指定なし)

図 4.8

構造体型の内部表現(構造体パッキング指定あり)

 

構造体パッキング指定については,「-pack」を参照してください。

(7)

共用体型

(a)

内部表現

共用体全体の整列条件は,その共用体で最も大きなメンバの整列条件に合わせたものとなります。このルールは,メンバが構造体や共用体の場合にも再帰的に適用されます。

union {
        int     u1;
        short   u2;
        char    u3;
        long    u4;
} tag;

 

この例に示した共用体に対する内部表現は,次のようになります。

図 4.9

共用体型の内部表現

(8)

ビット・フィールド

(a)

内部表現

ビット・フィールドには_Bool,char,signed char,unsigned char,signed short,unsigned short,signed int,unsigned int,signed long,unsigned long,signed long long,unsigned long long,および列挙型を指定することができます。

C90では(signed/unsigned)int 型のみ許されていますが,CC-RLではオプション-strict_stdを使用しない場合,上記の型を全てビット・フィールドに対して有効とします。オプション-strict_stdを使用する場合,_Bool,signed long long,unsigned longl long型はC90違反でエラーとします。

ビット・フィールドは,宣言した型の最下位ビットから割り当てます。

ビット・フィールドを直前のビット・フィールドに続くビットから配置すると,配置後のビット・フィールドの末尾の位置が,ビット・フィールドの整列条件を満たす直前の境界に「宣言した型のビット幅」を加えた位置を超える場合,そのビット・フィールドは直前のビット・フィールド以降にあるビット・フィールドの整列条件を満たす最初の境界に整列します。

-

signedもunsignedもつかない型のビット・フィールドは,符号なしとして扱われます。
ただし,オプション-signed_bitfield使用時は,符号付きとして扱われます。

-

割り付け単位内のビット・フィールドの割り付け順序は下位(LSB)から上位(MSB)となります。

例 1.

struct S{
        char            a;
        char            b:2;
        signed char     c:3;
        unsigned char   d:4;
        int             e;
        short           f:5;
        int             g:6;
        unsigned char   h:2;
        unsigned int    i:2;
};

この例に示したビット・フィールドに対する内部表現は,次のようになります。

図 4.10

ビット・フィールドの内部表現(構造体パッキング指定なし)

 

sizeof(struct S)=8

図 4.11

ビット・フィールドの内部表現(構造体パッキング指定あり)

 

sizeof(struct S)=7

例 2.

struct S{
        char    f1:4;
        int     f2:5;
        int     f3:6;
};

 

この例に示したビット・フィールドに対する内部表現は,次のようになります。

図 4.12

ビット・フィールドの内部表現

 

sizeof(struct S)=2

 

例 3.

struct S{
        long    f1:4;
};

 

この例に示したビット・フィールドに対する内部表現は,次のようになります。

図 4.13

ビット・フィールドの内部表現(構造体パッキング指定なし)

 

sizeof(struct S)=2

図 4.14

ビット・フィールドの内部表現(構造体パッキング指定あり)

 

sizeof(struct S)=1

 

構造体パッキング指定については,「-pack」を参照してください。

(9)

整列条件

(a)

基本型に対する整列条件

次に,基本型に対する整列条件を示します。

表 4.8

基本型に対する整列条件

基本型

整列条件

(unsigned)char

_Bool型

1バイト境界

上記以外

2バイト境界

(b)

列挙型に対する整列条件

次に,列挙型に対する整列条件を示します。

<1>

オプション-signed_charなし

列挙子の下限値

列挙子の上限値

内部表現の型

整列条件

-128

127

signed char

1

0

255

char

1

上記以外

signed short

2

<2>

オプション-signed_charあり

列挙子の下限値

列挙子の上限値

内部表現の型

整列条件

-128

127

char

1

0

255

unsigned char

1

上記以外

signed short

2

(c)

配列に対する整列条件

配列型に対する整列条件は,配列要素の整列条件と同じになります。

(d)

ポインタに対する整列条件

nearポインタ,farポインタに対する整列条件は,2となります。

(e)

共用体型に対する整列条件

共用体型に対する整列条件は,共用体を構成するメンバのうち,最大の整列条件をもつ型の整列条件と同じになります。

(f)

構造体型に対する整列条件

構造体型に対する整列条件は,構造体を構成するメンバのうち,最大の整列条件をもつ型の整列条件と同じになります。

(g)

関数引数に対する整列条件

9.1 関数呼び出しインタフェース」を参照してください。

(h)

関数に対する整列条件

関数に対する整列条件は,1バイト境界となります。