5

必要な定数値を記述する構造体を書いていて、奇妙なことに気付きました。

namespace res{
    namespace font{
        struct Structure{
            struct Glyph{
                int x, y, width, height, easement, advance;
            };
            int glyphCount;
            unsigned char asciiMap[];   // <-- always generates an error
            Glyph glyphData[];          // <-- never generates an error
        };
        const Structure system = {95, 
                              {
                                 // mapping data
                              }, 
                              {
                                 // glyph spacing data
                              }
        }; // system constructor
    } // namespace font
} // namespace res

の最後の 2 つのメンバーでStructureあるサイズ変更されていない配列は、単独である場合、コンパイラを停止しません。ただし、構造体の定義に両方が含まれていると、「型が不完全です」というエラーが発生します。

最初の配列にサイズを指定すると、これは問題になりません。この場合、これは問題ではありませんが、私はまだ興味があります...

私の質問は、構造体にサイズのない配列を 1 つ持つことができるのに、2 つあると問題が発生するのはなぜですか?

4

5 に答える 5

5

一部のコンパイラは拡張機能としてサポートしていますが、標準 C++ ではこれを行うことはできません。

C では、 a のすべてのメンバーがstruct内で固定位置を持つ必要がありますstruct。これは、最後のメンバーのサイズが不明になる可能性があることを意味します。しかし、その後には何も来ることができないため、未知のサイズのメンバーを複数持つ方法はありません。

C++ でのこのハックに対するコンパイラの非標準サポートを利用する場合は、 のいずれかのメンバーがstruct自明でない場合、事態がひどく悪化する可能性があることに注意してください。オブジェクトは、生メモリのブロックを割り当て、それをこの型として再解釈することによって、最後に空でない配列でのみ「作成」できます。これを行うと、コンストラクタまたはデストラクタは呼び出されません。

于 2012-12-20T11:51:29.737 に答える
3

非標準の Microsoft 拡張機能を使用しています。C11 (注: C であり、C++ ではありません) では、構造体の最後の配列のサイズを変更できます (読み取り:最大1 つの配列)。

Microsoft 拡張により、C または C++ の構造体またはクラスの最後のメンバーを可変サイズの配列にすることができます。これらは、サイズのない配列と呼ばれます。構造体の末尾にあるサイズのない配列を使用すると、可変サイズの文字列またはその他の配列を追加できるため、ポインター逆参照の実行時の実行コストを回避できます。

// unsized_arrays_in_structures1.cpp
// compile with: /c
struct PERSON {
   unsigned number;
   char name[];   // Unsized array
};

この構造体に sizeof 演算子を適用すると、最後の配列サイズは 0 と見なされます。この構造体のサイズは 2 バイトで、これは符号なしメンバーのサイズです。PERSON 型の変数の実際のサイズを取得するには、配列サイズを個別に取得する必要があります。

構造体のサイズが配列のサイズに追加され、割り当てられる合計サイズが取得されます。割り当て後、以下に示すように、配列は構造体の配列メンバーにコピーされます。

于 2012-12-20T11:46:52.193 に答える
2

コンパイラは、構造体内のすべてのメンバーのオフセットを決定できる必要があります。そのため、サイズのない配列の後にそれ以上のメンバー配置することはできません。このことから、構造体に 2 つのサイズのない配列を含めることはできません。

于 2012-12-20T11:48:33.390 に答える
1

これは、Microsoftおよびsizeof(structure) == sizeof(structure_without_variable_size_array).

配列のサイズを見つけるために初期化子を使用していると思います。可変サイズの配列が 2 つある場合、それを見つけることはできません (方程式が 1 つしかない 2 つの未知のシステムの一意の解を 1 つ見つけることと同じです...)

于 2012-12-20T11:48:47.817 に答える
1

次元のない配列はstruct、少なくとも C++ ではピリオドでは許可されません。C では、最後のメンバー (および最後のメンバーのみ) を次元なしで宣言できます。一部のコンパイラでは、拡張機能として C++ でこれを許可していますが、それを当てにするべきではありません (厳密モードでは、少なくとも文句を言う必要があります)。それについて)。最後の要素の次元が 0 の場合、他のコンパイラは同じセマンティクスを実装しています (厳密モードでの診断が必要な拡張もあります)。

不完全な配列型を最後の要素に制限する理由は単純です。次の要素のオフセットはどうなるでしょうか? 最後の要素であっても、結果の構造体の使用には制限があります。たとえば、別の構造体または配列のメンバーにすることはできず、 sizeofこの最後の要素は無視されます。

于 2012-12-20T11:58:19.450 に答える