静态数组定义为未指定大小、空括号?

发布于 2024-08-30 12:47:50 字数 749 浏览 15 评论 0原文

对于下面的 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 专用)。

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

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

For the C++ code fragment below:

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
}

why isn't the member variable causing an error too? and what is the meaning of this member variable?

I'm using gcc version 3.4.5 (mingw-vista special) through CodeBlocks 8.02.

On Visual Studio Express 2008 - Microsoft(R) C/C++ Optimizing Compiler 15.00.30729.01 for 80x86, I got the following messages:

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
}

Now, this needs some explaination too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乖乖兔^ω^ 2024-09-06 12:47:50

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

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

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

C++ language allows omitting array size only in non-defining declarations

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

Non-static class member decarations are always required to specify the array size

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

while static class member decarations can omit the size

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

(the definition of the same member will, of course, have to specify the size).

Any deviations from this behavior can only be explaind by extended non-standard behavior of your compiler. Maybe you should specify some additional compiler settings to make it behave in more pedantic fashion.

小苏打饼 2024-09-06 12:47:50

C99 支持所谓的“灵活”数组成员,它允许作为结构的最后一个成员。当您动态分配此类结构时,您可以增加从 malloc() 请求的数量,以为数组提供内存。

一些编译器将其添加为 C90 和/或 C++ 的扩展。

因此,您可以使用如下代码:

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


void use_foo(size_t bufSize)
{
    struct foo_t* p = (foo_t*) malloc( sizeof( struct foo_t) + bufSize);
    
    int i;
    
    for (i = 0; i < bufSize; ++i) {
        p->buf[i] = i;
    }
}

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

老实说,我不确定如何通过 C++ 的 new 运算符轻松使用这样的东西 - 我认为您必须使用 malloc() 为对象分配内存> 并使用放置new。也许可以使用operator new的某些类/结构特定重载......

C99 supports something called a 'flexible' array member that is allowed to be the last member of a struct. When you dynamically allocate such a struct you can increase the amount requested from malloc() to provide for memory for the array.

Some compilers add this as an extension to C90 and/or C++.

So you can have code like the following:

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


void use_foo(size_t bufSize)
{
    struct foo_t* p = (foo_t*) malloc( sizeof( struct foo_t) + bufSize);
    
    int i;
    
    for (i = 0; i < bufSize; ++i) {
        p->buf[i] = i;
    }
}

You can't define a struct with a flexible array member directly (as a local or a global/static variable) as the compiler won't know how much memory to allocate for it.

I'm honestly not sure how you'd easily use such a thing with C++'s new operator - I think you'd have to allocate the memory for the object using malloc() and use placement new. Maybe some class/struct specific overload of operator new could be used...

北方的巷 2024-09-06 12:47:50
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 的定义必须包含大小规范或具有指定大小的数组的初始化。

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.

An array type with unspecified size is incomplete. 8.3.4/1:

If the constant expression is omitted, the type of the identifier of D is “derived-declarator-type-list array of unknown bound of T”, an incomplete object type.

It must be completed in order to participate in a definition, ie the definition of a must contain a size specification or initialization with an array of specified size.

毅然前行 2024-09-06 12:47:50

我们用它来表示某种可变长度记录。类似头文件的东西,其中包含有关要遵循多少个结构的信息,后面是数据本身。它是一个可变长度数组,我发现编译器之间并没有很好地支持它。有些想要 array[];有些想要 array[0]; (旧样式)。

We've used this to denote a variable length record of some sort. Something like a header file that has information on how many structures to follow, followed by the data itself. It's a variable length array and I've found it is not supported well between compilers. Some want array[]; and some want array[0]; (old style).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文