对静态数组的初始化列表大小错误发出警告

Issue warning for wrong size of initialiizer list of static array

本文关键字:错误 警告 列表 静态 数组 初始化      更新时间:2023-10-16

非常简短:如何在gcc和/或VS中为以下代码启用警告:

const int array[4] = {1, 2};

长版本:我有一个具有常量属性的表。基本上,它定义了两个"对象"如何交互。为此,我有一个有3个维度的表:环境,第一对象,第二对象。有3种不同的环境(enum)和~20个对象。所以这个数组看起来像:

const int property[3][20][20] = {{{...}}, {{...}}, {{...}}};

(在实际代码中,3和20是枚举的实际计数常数。也可以将整型转换为enum,但这不是重点。)
因此,对属性[e][t1][t2]的访问意味着:我应该如何处理环境e中的会议t1->t2 ?注意,这通常不同于t2->t1!

实际上,我更喜欢那些对未使用的enum成员发出警告的开关,但在这种情况下,开关将被嵌套3次,因此非常冗长/庞大。

如果有人能想出更好的办法,我就接受。在此之前,如果我没有填充数组元素,我希望至少有一个警告。

提供小于数组大小的初始化式是一种广泛使用的特性。编写如下代码

int array[100] = {0};

是默认初始化所有数组元素的常用方法。目前,gcc没有提供一个开关来警告这个问题。

一个只适用于顶级数组的解决方案是使用static_assert,并删除显式大小,如下所示:

const int array[] = {1, 2, 3, 4};
//             ^^
//     No explicit size
// Check the size here:
static_assert(sizeof(array)/sizeof(array[0]) == 4, "Expected four elements");

这样,如果数组的初始化项的数量不等于您期望的数量(即四个),您将获得编译时错误。

您可以创建一个瘦int包装器,给它一个构造函数,并使用该包装器类型的数组。这不仅会给你一个警告,甚至一个错误:

struct Integer
{
    Integer(int i) : i(i) {}
    int i;
};
int main()
{
   const Integer array[4] = {1, 2};
}
VC错误:

error C2073: 'array' : elements of partially initialized array must have a default constructor

GCC错误:

error: no matching function for call to 'Integer::Integer(<brace-enclosed initializer list>)'

如果使用这种解决方案,那么还可以考虑使用转换操作符:

struct Integer
{
    Integer(int i) : i(i) {}
    int i;
    operator int() const { return i; }
};
void f(int x) {}
int main()
{
   const Integer array[4] = {1, 2, 3, 4};
   f(array[0]);
}