关于声明多维双数组的警告

g++ warning on declaring multidimensional, double array

本文关键字:数组 警告 于声明 声明      更新时间:2023-10-16

在我的c++程序中,我试图初始化一个类型为3*3*3的双精度数组,所有的0。在类头文件中,我声明了一个成员

double list[3][3][3];

当我打印出这个数组的内容时,我发现并不是所有的条目都像我期望的那样是0。例如,list[1][1][1]的值为4.03158e-321

因此,我手动将这个数组初始化为构造函数中的所有0:

list = {{{0,0,0},{0,0,0},{0,0,0}},
      {{0,0,0},{0,0,0},{0,0,0}},
      {{0,0,0},{0,0,0},{0,0,0}}};

这使我的程序工作,然而,我得到编译器警告:

warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

所以我的问题是

  1. 为什么list在初始化后有非零条目头吗?
  2. 为什么我得到上述警告消息,以及如何摆脱它?

我的编译器是g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2, gcc版本4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)

在c++ 03中,你只能在定义数组时使用这个初始化:

double list[3][3][3] = {{{0,0,0},{0,0,0},{0,0,0}},
                        {{0,0,0},{0,0,0},{0,0,0}},
                        {{0,0,0},{0,0,0},{0,0,0}}};

编译器警告,根据当前的标准,它不应该接受你的代码,即使它能够通过应用即将到来的标准规则来处理它,其中{...}被称为外部初始化器

在这种特殊情况下,如果数组是一个成员,并且您希望将其初始化为全零,则可以在c++ 0x:

中使用value-initialization
struct test { 
   double list[3][3][3];
   test() : list()
   {}
};

对于POD类型的成员(double的数组),上面的语法(list())在初始化列表中意味着该成员是值初始化的,这实际上意味着所有值将被设置为0

是我错过了什么,还是你可以不做

class Class {
public:
    double array[3][3][3];
    Class() : array() { }
};
  1. 头文件中没有初始化,只是声明了。内置类型(以及更一般的pod)如果不是全局类型(实际上,它们具有静态存储持续时间),则不会出于性能原因自动进行零初始化(与c++中的许多事情一样,初始化是可选的,只有在需要时才付费)。

  2. 该语法仅在初始化数组时有效,而该指令是赋值。在新的c++标准(以前是c++ 0x,现在是c++ 11,因为它刚刚被批准)中,这种语法可以在更多的地方使用。

在我看来,解决你的问题最快的方法就是这样做:

double * firstElem=&list[0][0][0];
std::fill(firstElem, firstElem+27, 0.);

list视为由27个double组成的一维数组,并将其填充为零(这里有关于该技巧的更多信息)。

注意,这个参数也在数组FAQ中被简单处理过。

有一种更简单的方法。以下代码应该在C或c++中工作,仅用于初始化变量(即不在赋值中):

double list[3][3][3] = {0};

{0}是一个特殊的初始化器,它可以将几乎所有结构设置为全零。

为什么不使用memset或loop将值设置为零呢?