头文件中的C ++零长度数组

时间:2014-07-11 21:33:58

标签: c++

来自ISO / IEC 14882:2003 8.3.4 / 1:

  

如果存在常量表达式(5.19),它应该是一个整数   常量表达式及其值应大于零。

因此,以下内容不应编译:

#pragma once
class IAmAClass
{
public:
    IAmAClass();
    ~IAmAClass();

private:
    int somearray[0];    // Zero sized array
};

但确实如此。但是,以下内容:

#pragma once
class IAmAClass
{
public:
    IAmAClass();
    ~IAmAClass();

private:
    int somearray[0];
    int var = 23;     // Added this expression
};

无法编译,出现以下错误(正如预期的那样)(Visual C ++)

error C2229: class 'IAmAClass' has an illegal zero-sized array

当代码在函数中时,它将根据标准永远不会编译。

那么,为什么代码在头文件中以这种方式运行,其中编译传递或失败的差异似乎取决于语句是否继续进行零大小的数组声明。

2 个答案:

答案 0 :(得分:6)

&#34中的关键字;如果存在常量表达式(5.19),"是如果。它不是,所以第一个版本编译。

然而,当这些变体数组是structclass中的 last 元素时,它们才是允许的(并且是理智的)。他们将根据具体情况使用分配给结构的额外空间。

如果在其他元素之前允许一个未知长度的数组,那么其他代码如何知道内存中的 where 以找到这些元素?

答案 1 :(得分:3)

这是Visual C ++语言扩展:Declaring Unsized Arrays in Member Lists。从链接的MSDN页面:

  

如果程序未使用ANSI兼容性选项(/Za)进行编译,则可以将未大小的数组声明为类成员列表中的最后一个数据成员


编辑:如果成员已被声明为零大小的数组(如int somearray[0];)而不是未知边界数组(如int somearray[];),则这是仍然语言扩展名,尽管是a different one

  

只有当数组是结构或联合中的最后一个字段以及启用Microsoft扩展(/ Ze)时,零大小的数组才是合法的。


此扩展类似于C99的灵活数组成员 C11 /n1570§6.7.2.1/ 18

  

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活的数组成员

和/ 20包含一个例子:

  

示例2声明后:

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;
     

[...]