可变大小的数组作为类成员:为什么要编译?

时间:2014-02-24 14:14:02

标签: c++ g++ mingw

我有这种情况,我无法解释为什么编译:

#include <iostream>
using namespace std;

class X {
public:
    X() {cout << "in X constructor: " << endl;};
};

class Y {
public:
    Y() {cout << "in Y constructor" << endl;};
private:    
    X x[];
};

int main() {
    Y y;
    return 0;
}

我将X的可变大小数组定义为类Y的成员。定义X它在类之外的方式肯定会导致编译错误,但不会在类中。更重要的是,X的构造函数永远不会被调用。

那么这里发生了什么?

1 个答案:

答案 0 :(得分:11)

C99,6.7.2.1/16(n1256)

  

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可以   有一个不完整的数组类型;这称为灵活数组成员。在大多数情况下,   灵活的数组成员被忽略。特别是,结构的大小就像是   省略了灵活的数组成员,除了它可能有更多的尾随填充   遗漏意味着。

它不是可变长度数组。它不像数据成员,更像是告诉编译器你可以通过灵活数组成员的名称访问某些内存的接口。

/ 17

  

示例声明后:

struct s { int n; double d[]; };
     

结构struct s具有灵活性   数组成员d。使用它的典型方法是:

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
     

并假设对malloc的调用成功,p指向的对象   在大多数情况下,表现为p被声明为:

struct { int n; double d[m]; } *p;

这在C ++ 11中是不允许的,但是作为扩展名被g ++和clang ++接受。由于struct(对于C ++)的构造函数不知道元素的数量,构造函数无法(自动)初始化这些元素。