用未指定大小定义的静态数组,空括号?

Ahm*_*der 9 c++ compiler-construction class static-array

对于下面的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
}
Run Code Online (Sandbox Code Playgroud)

为什么成员变量也不会导致错误?这个成员变量的含义是什么?

我通过CodeBlocks 8.02使用gcc版本3.4.5(mingw-vista special).

在Visual Studio Express 2008 - Microsoft(R)C/C++ Optimizing Compiler 15.00.30729.01 for 80x86上,我收到以下消息:

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
}
Run Code Online (Sandbox Code Playgroud)

现在,这也需要一些解释.

AnT*_*AnT 12

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
Run Code Online (Sandbox Code Playgroud)

始终需要非静态类成员decarations来指定数组大小

struct S {
  int a[]; // ERROR in C++
};
Run Code Online (Sandbox Code Playgroud)

而静态类成员decarations可以省略大小

struct S {
  static int a[]; // OK in C++
};
Run Code Online (Sandbox Code Playgroud)

(当然,同一成员的定义必须指定大小).

任何与此行为的偏差都只能通过编译器的扩展非标准行为来解释.也许您应该指定一些额外的编译器设置,使其表现得更加迂腐.


Mic*_*urr 8

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您无法直接使用灵活的数组成员定义结构(作为本地或全局/静态变量),因为编译器不知道要为其分配多少内存.

老实说,我不确定你如何轻易地使用C++的new运算符这样的东西- 我认为你必须为使用malloc()和使用位置的对象分配内存new.也许operator new可以使用一些类/结构特定的重载...