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

Dav*_*vic 7 c++ mingw g++

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

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

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

那么这里发生了什么?

dyp*_*dyp 11

C99,6.7.2.1/16(n1256)

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型; 这被称为灵活的阵列成员.在大多数情况下,将忽略灵活数组成员.特别地,结构的尺寸好像省略了柔性阵列构件,除了它可以具有比省略意味着更多的拖尾填充.

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

/ 17

示例声明后:

struct s { int n; double d[]; };
Run Code Online (Sandbox Code Playgroud)

该结构struct s具有灵活的阵列成员d.使用它的典型方法是:

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
Run Code Online (Sandbox Code Playgroud)

并且假设调用malloc成功,p 对于大多数目的,行为所指向的对象就像p被声明为:

struct { int n; double d[m]; } *p;
Run Code Online (Sandbox Code Playgroud)

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