Cが標準化される前は、コードがゼロサイズ型へのポインタを別のポインタから減算しようとしない限り、多くのコンパイラはゼロサイズ型の処理に問題はありませんでした。そのようなタイプは有用であり、それらをサポートすることはそれらを禁止するよりも簡単で安価でした。ただし、他のコンパイラはそのような型を禁止することを決定しました。一部の静的アサーションコードは、コードがゼロサイズの配列を作成しようとするとスクォークするという事実に依存している可能性があります。標準の作成者は、次の選択肢に直面しました。
コンパイラがゼロサイズの配列宣言をサイレントに受け入れることを許可します。そのような宣言の目的が診断をトリガーしてコンパイルを中止する場合でも、すべてのコンパイラがゼロサイズのオブジェクトを生成するものとしてそのような宣言を受け入れることを要求します(必ずしもサイレントではありません)。 。
コンパイラーがゼロサイズの配列宣言をサイレントに受け入れることを許可します。そのような宣言の目的が診断をトリガーしてコンパイルを中止する場合でも、そのような宣言に遭遇したコンパイラーはコンパイルを中止するか、自由に続行できます。
コードがゼロサイズの配列を宣言している場合、実装が診断を発行することを要求しますが、その後、実装がコンパイルを中止するか、(適切と思われるセマンティクスで)自由にコンパイルを続行できるようにします。
標準の作成者は#3を選択しました。その結果、ゼロサイズの配列宣言は、標準がそれらを禁止する前にそのような構造が広くサポートされていたとしても、標準の「拡張」によって見なされます。
C ++標準では、空のオブジェクトの存在が許可されていますが、空のオブジェクトのアドレスをトークンとして使用できるようにするために、最小サイズは1であることが義務付けられています。メンバーがないオブジェクトの場合、したがって、0は標準に違反します。ただし、オブジェクトにゼロサイズのメンバーが含まれている場合、C ++標準では、そのような宣言を含むプログラムが診断をトリガーする必要があるという事実以外に、オブジェクトの処理方法に関する要件はありません。このような宣言を使用するほとんどのコードは、結果のオブジェクトのサイズがゼロであることを想定しているため、このようなコードを受け取るコンパイラーにとって最も有用な動作は、それらをそのように扱うことです。