开发者

brace-enclosed initializer list

assuming I have an object similar to this one:

struct MenuDef
{
    int titleResourceId;

    struct MenuItemDef {
        char*               name;
        int                 value;
        SomeFunctionPtr     someFactory;
    } menuItems[10];
};

That is initialized like this:

const MenuDef m = {
    1,
    {
        {
            "zero",
            0,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "one",
            1,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "two",
            2,
            (SomeFunctionPtr) & MenuButton::factory,
        },
    }
};

Is it safe to assume that m.menuItems[3].someFactory == 0 ?

for example in a loop like this:

for ( int i = 0; m.menuItems[i].someFactory != 0; ++i)

or do I have to insert a 开发者_运维知识库last element to mark the array end by hand just to be safe?

...
        {
            "two",
            2,
            (SomeFunctionPtr) & MenuButton::factory,
        },
        {
            "",
            0,
            (SomeFunctionPtr) 0,
        },
...


I believe it is safe according to 8.5.1/7 :

If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5).

As a reminder :

To value-initialize an object of type T means:

  • if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;
  • if T is an array type, then each element is value-initialized;
  • otherwise, the object is zero-initialized


The answer to your question depends on the language version (C++98 or C++03) and, in C++98, on some details you failed to provide. Namely, what is SomeFuncPtr? Is this an ordinary function pointer or a member function pointer?

If this is a member function pointer, then in C++98 version of language specification the inner class is not POD. Since it is a non-POD class, the remaining array members will be default-initialized by calling their default constructors. The compiler-provided default constructor for the inner class does nothing, so the remaining members of the array will contain garbage.

In C++03 version of language specification the remaining array members are value-initialized, which will indeed zero-initialize the rest of the array, regardless of what SomeFuncPtr is.

So, if you are using a C++03-compliant compiler, you are fine. If you care about being backward portable to C++98 compilers, you might want to include that explicit terminating initializer (depending, again, on what SomeFuncPtr is).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜