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 - 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
}

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

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++ 的new运算符轻松使用这样的东西 - 我认为您必须为对象分配内存 usingmalloc()和 use placement new。也许可以使用某些类/结构特定的重载operator 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

我们用它来表示某种可变长度的记录。类似于头文件,其中包含有关要遵循多少结构的信息,然后是数据本身。这是一个可变长度数组,我发现编译器之间不支持它。有些人想要数组[]; 有些人想要数组[0];(老款式)。

于 2010-04-27T00:01:50.097 回答