我会导致“初始化程序太少”出现编译错误吗?

发布于 2024-09-18 00:45:14 字数 775 浏览 7 评论 0原文

我正在使用聚合初始值设定项来设置用于单元测试的静态数据块。

我想使用数组大小​​作为预期的元素数量,但如果提供的初始值设定项太少,这可能会失败:

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 个点的编译时保证,这会从提供值的 end of the array 末尾运行到默认初始化值。

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

I am using an aggregate initializer to set up a block of static data for a unit test.

I would like to use the array size as the expected number of elements, but this can fail if too few initializers are provided:

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

This gives no compiler error in Visual Studio 2008.

I would like to be able to use it as such:

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);
}

but because I don't have a compile-time guarantee of 14 points, this runs off the end of the array end of the provided values and into the default-initialized values.

Can I somehow enforce the number of aggregate array initializers at compile-time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

压抑⊿情绪 2024-09-25 00:45:14

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

如果您试图确保配置了特定数量的初始值设定项,我不知道该怎么做。

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

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

就可以了。然后只需使用 sizeof(expected) / sizeof(expected[0]) 即可获取数组元素的总数。

Actually it won't run off the end of the array, because the compiler will default-initialize all the elements of the array that you didn't initialize yourself.

If you're trying to make sure that you have a specific number of configured initializers, I'm not sure how to do that.

If you just want to make sure the array is the number of items you have:

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

Will do the trick. Then just use sizeof(expected) / sizeof(expected[0]) to get the total number of array elements.

江南月 2024-09-25 00:45:14

第一:可能会出现警告。您是否尝试过以最高警告级别进行编译?

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

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 );

First: There might be a warning for this. Have you tried compiling at the highest warning level?

Then: If you swap which value is calculated and which is literal, you could raise a compile-time error:

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 );
风吹过旳痕迹 2024-09-25 00:45:14

只是为了非 Boost 答案......

您可以通过修改 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。

Just for the sake of a non-Boost answer…

You can add an initialization requirement by modifying 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 is still an aggregate, but it is not POD.

落花随流水 2024-09-25 00:45:14

ISO/IEC 14882(第一版 1998-09-01)第 14 页8.5.1.7 规定如下:

如果初始化程序较少
列表中的成员数多于
聚合,那么每个成员不
显式初始化应为
默认初始化(8.5)。 [例子:
结构 S { int a;字符* b;整数c; }; S
ss = { 1, "asdf" };初始化 ss.a
与 1、ss.b 与“asdf”和 ss.c
与表达式的值
形式为int(),即0。]

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

ISO/IEC 14882 (First edition 1998-09-01) in p. 8.5.1.7 states the following:

If there are fewer initializers in the
list than there are members in the
aggregate, then each member not
explicitly initialized shall be
default-initialized (8.5). [Example:
struct S { int a; char* b; int c; }; S
ss = { 1, "asdf" }; initializes ss.a
with 1, ss.b with "asdf", and ss.c
with the value of an expression of the
form int(), that is, 0. ]

Simply, the answer to your question is no.

没企图 2024-09-25 00:45:14

根据 msdn,如果初始化程序较少指定后,其余元素将初始化为 0,因此代码仍然可以工作。

According to the msdn, if fewer initializers are specified, the remaining elements are initialized with 0, so the code should work nonetheless.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文