10

以下のC++コードフラグメントの場合:

class Foo {
    int a[]; // no error
};

int a[];     // error: storage size of 'a' isn't known

void bar() {
    int a[]; // error: storage size of 'a' isn't known
}

メンバー変数もエラーを引き起こさないのはなぜですか?そして、このメンバー変数の意味は何ですか?

CodeBlocks 8.02からgccバージョン3.4.5(mingw-vista special)を使用しています。

Visual Studio Express 2008-80x86用のMicrosoft(R)C / C ++最適化コンパイラ15.00.30729.01で、次のメッセージが表示されました。

class Foo {
    int a[]; // warning C4200: nonstandard extension used : zero-sized array in struct/union - Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
};

int a[];

void bar() {
    int a[]; // error C2133: 'a' : unknown size
}

さて、これにもいくつかの説明が必要です。

4

4 に答える 4

13

C++ 言語では、未定義の宣言でのみ配列サイズを省略できます

extern int a[]; // non-defining declaration - OK in C++

int a[]; // definition - ERROR in C++

int a[5]; // definition - OK, size specified explicitly
int a[] = { 1, 2, 3 }; // definition - OK, size specified implicitly

配列サイズを指定するには、非静的クラス メンバーの宣言が常に必要です。

struct S {
  int a[]; // ERROR in C++
};

一方、静的クラス メンバーの宣言ではサイズを省略できます。

struct S {
  static int a[]; // OK in C++
};

(もちろん、同じメンバーの定義ではサイズを指定する必要があります)。

この動作からの逸脱は、コンパイラの拡張された非標準動作によってのみ説明できます。たぶん、いくつかの追加のコンパイラ設定を指定して、よりペダンティックな方法で動作させる必要があります。

于 2010-04-27T00:04:34.257 に答える
9

C99 は、構造体の最後のメンバーにできる「柔軟な」配列メンバーと呼ばれるものをサポートしています。このような構造体を動的に割り当てるmalloc()と、配列にメモリを提供するために要求される量を増やすことができます。

一部のコンパイラは、これを C90 や C++ の拡張機能として追加します。

したがって、次のようなコードを作成できます。

struct foo_t {
    int x;
    char buf[];
};


void use_foo(size_t bufSize)
{
    struct foo_t* p = malloc( sizeof( struct foo_t) + bufSize);

    int i;

    for (i = 0; i < bufSize; ++i) {
        p->buf[i] = i;
    }
}

柔軟な配列メンバーを持つ構造体を直接 (ローカル変数またはグローバル/静的変数として) 定義することはできません。これは、コンパイラーがそれに割り当てるメモリ量がわからないためです。

正直なところ、C ++の演算子でそのようなことを簡単に使用する方法がわかりません.placementを使用しnewてオブジェクトにメモリを割り当てる必要があると思います。たぶん、いくつかのクラス/構造体固有のオーバーロードを使用できます...malloc()newoperator new

于 2010-04-26T23:46:30.623 に答える
2
class Foo {
    int a[]; // OK in C, invalid in C++. Does not work with inheritance.
}; // Idea is that structure is "extended" indefinitely by an array.
   // May work on your compiler as an extra feature.

int a[];     // error in C and C++: storage size of 'a' isn't known

void bar() {
    int a[]; // error in C and C++: storage size of 'a' isn't known
}

extern int a[]; // OK: storage size may be declared later.

int a[5]; // declaration of size before use.

サイズが指定されていない配列型は不完全です。8.3.4/1:

定数式を省略した場合、D の識別子の型は「T の境界が不明な派生宣言子型リスト配列」という不完全なオブジェクト型になります。

定義に参加するには、これを完了する必要があります。つまり、 の定義にaは、サイズの指定または指定されたサイズの配列による初期化が含まれている必要があります。

于 2010-04-26T23:40:22.883 に答える
0

これを使用して、ある種の可変長レコードを示しました。従うべき構造の数に関する情報と、それに続くデータ自体を含むヘッダーファイルのようなもの。これは可変長配列であり、コンパイラ間で十分にサポートされていないことがわかりました。配列が欲しい人もいます[]; また、array[0]が必要な場合もあります。(古いスタイル)。

于 2010-04-27T00:01:50.097 に答える