Oracle Solaris Studio 12.2: C ユーザーガイド

6.12 互換型と複合型

K&R C では (ISO C の場合はさらに顕著ですが)、同じ要素を参照する 2 つの宣言を別のものとして扱うことができます。ISO C は、このような「ある程度似ている」型を示すために、「互換型」という用語を使用します。この節では、この互換型と、2 つの互換型を結合した「複合型」を説明します。

6.12.1 複数の宣言

C プログラムにおいて各オブジェクトまたは関数の宣言が 1 度しか許されていないのであれば、互換型は必要ないはずです。しかし、同じ要素を参照する複数の宣言を許可するリンク、関数のプロトタイプ、および分割コンパイルには、このような機能が必要です。複数の翻訳単位 (ソースファイル) 間では、型の互換性の規則は 1 つの翻訳単位内のものとは異なります。

6.12.2 分割コンパイル間の互換性

各コンパイルでは別々のソースファイルを参照するため、分割コンパイル間の互換型に対して、ほとんどの規則の内容は次のように構造化されています。

6.12.3 単一のコンパイルでの互換性

同じスコープ内の 2 つの宣言が同じオブジェクトまたは関数を記述するとき、この 2 つの宣言は互換型を指定しなければいけません。これら 2 つの型は次に、最初の 2 つと互換性を持つ、1 つの複合型に結合されます。複合型についてはあとで説明します。

互換型は再帰的に定義されます。一番下は型指定子のキーワードです。これらの規則は、unsigned shortunsigned short int と同じであり、型指定子なしの型は int を持つ型と同じであることを示します。ほかのすべての型は、派生元の型が互換性を持つときだけ、互換性を持ちます。たとえば、修飾子 constvolatile が同じであり、修飾されていない基底型が互換性を持つ場合、2 つの修飾型は互換性を持ちます。

6.12.4 互換ポインタ型

2 つのポインタ型が互換性を持つためには、この 2 つのポインタが指す型が互換性を持ち、2 つのポインタが同じように修飾されていなければいけません。ポインタの修飾子は * のあとに指定されることを念頭に置いて、次の例を見てください。


int *const cpi;
int *volatile vpi;

前述の 2 つの宣言は、同じ型 int を指すが修飾が異なる 2 つのポインタを宣言しています。

6.12.5 互換配列型

2 つの配列型が互換性を持つためには、この 2 つの配列の要素の型が互換性を持たなければいけません。両方の配列の型のサイズが指定されている場合は、両方のサイズも一致しなければいけません。つまり、不完全な配列型 (「6.11 不完全な型」を参照) は、ほかの不完全な配列型とも、サイズが指定されている配列型とも互換性を持ちます。

6.12.6 互換関数型

関数が互換性を持つためには、次の規則に従わなければいけません。

6.12.7 特別な場合

signed intint と同じように動作します。ただし、ビットフィールドで通常の int が unsigned 動作を示す数になる場合を除きます。

また、列挙型は同じ整数型と互換性を持たなければいけません。移植可能なプログラムの場合、これは、列挙型が別の型であることを意味します。一般的に、ISO C 規格はこのように列挙型を扱います。

6.12.8 複合型

2 つの互換型から 1 つの複合型への作成も再帰的に定義されます。不完全な配列型や古い形式の関数型を使用することにより、互換型をお互いに異なるようにできます。同様に、複合型をもっとも簡単に記述するには、元の両方の型 (元の型のすべての使用可能な配列サイズとパラメータリストも含む) と型の互換性を持たせればよいでしょう