1

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, }, ... 
2
  • 1
    This doesn't answer your question (I think @icecrime got it right) but the fact that you have to cast the function addresses in the initialization should be a big red flag. Even if it seems to work now, something might change in your compiler in the future and it will fail to work due to casting between incompatible function pointer types. Commented Dec 27, 2010 at 15:30
  • @Mark B not sure what you mean... can you provide an example? Commented Dec 27, 2010 at 17:11

2 Answers 2

4

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
Sign up to request clarification or add additional context in comments.

7 Comments

Do you not need a default constructor to initialise the values to 0? I'd also recommend against relying on this, storing the size instead to make it more readable or even changing to a vector.
@marcog: updated my answer with the definition of value-initialization. According to this quote, I believe that you do not need a user-declared constructor.
Isn't a struct a class type?
@marcog: here we have a non-union class type without a user-declared constructor (bullet 2)
@marcog storing the size seems more error prone than this approach. Using would be my usual recommendation too, but it would be almost impossible to change the codebase now and vectors are not so straightforward to initialize.
|
2

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

2 Comments

Ok. I get people not wanting C++0x answers. But, come on, you don't have to deal with C++98.
+1. Actually it is a static member function (which is pretty much the same as a ordinary function pointer). But thanks for clarifying, since I am not sure a C++03-compliant compiler is available for all of the platforms I have to deploy. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.