我可以在“初始化程序太少”时导致编译错误吗?

时间:2010-09-07 15:00:40

标签: c++ compiler-errors aggregate initializer-list boost-test

我正在使用聚合初始化程序为单元测试设置静态数据块。

我想将数组大小用作预期的元素数,但如果提供的初始化程序太少,则可能会失败:

my_struct_type expected[14] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

这在Visual Studio 2008中没有出现编译器错误。

我希望能够这样使用它:

const unsigned expected_size = sizeof(expected) / sizeof(my_struct_type);

BOOST_CHECK_EQUAL(points.size(), expected_size);

for( int i = 0; i < expected_size; i++ )
{
    BOOST_CHECK_EQUAL(points[i].value, expected[i].value);
    BOOST_CHECK_EQUAL(points[i].count, expected[i].count);
    BOOST_CHECK_EQUAL(points[i].sym,   expected[i].sym);
}

但是因为我没有14点的编译时保证,所以它会运行所提供值的数组结尾的结束并进入默认初始化值。

我可以在编译时以某种方式强制执行聚合数组初始值设定项的数量吗?

5 个答案:

答案 0 :(得分:5)

实际上它不会在数组的末尾运行,因为编译器将默认初始化你没有自己初始化的数组的所有元素。

如果您正在尝试确保您具有特定数量的已配置初始值设定项,我不确定如何执行此操作。

如果您只想确保数组是您拥有的项目数:

my_struct_type expected[] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

会做的伎俩。然后只需使用sizeof(expected) / sizeof(expected[0])来获取数组元素的总数。

答案 1 :(得分:4)

首先:可能会有此警告。您是否尝试过以最高警告级别进行编译?

然后:如果你交换计算的是哪个值,哪个是文字,你可能会引发编译时错误:

my_struct_type my_array[] = // <== note the empty []
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
};

BOOST_STATIC_ASSERT( sizeof(my_array)/sizeof(my_array[0]) == 14 );

答案 2 :(得分:1)

只是为了非促销的答案......

您可以通过修改my_struct_type来添加初始化要求。

template< typename T >
struct must_be_initialized {
    T value;

    must_be_initialized( T const &v ) : value( v ) {}
     // no default constructor!

    operator T& () { return value; }
    operator T const& () const { return value; }
};

struct my_struct_type {
    must_be_initialized< double > f;
    int i;
    char c;
};

my_struct_type expected[14] =
{
    { 1.234, 0, 'c' },
    { 3.141, 1, 'z' },
    { 2.718, 0, 'a' }
     // error: no default constructor exists
};

my_struct_type仍然是一个聚合,但它不是POD。

答案 3 :(得分:1)

ISO / IEC 14882(第一版1998-09-01),第4页。 8.5.1.7陈述如下:

  

如果初始化程序较少   列表中的成员比   聚合,然后每个成员不   明确初始化应为   default-initialized(8.5)。 [例:   struct S {int a; char * b; int c; };小号   ss = {1,“asdf”};初始化ss.a   用1,ss.b用“asdf”和ss.c   用表达式的值   form int(),即0.]

简单来说,问题的答案是否定的。

答案 4 :(得分:0)

根据msdn,如果指定的初始值设定项较少,则剩余的元素初始化为0,因此代码应该可以正常工作。