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).
精彩评论