saulspatz saulspatz - 2 months ago 18
C++ Question

What do empty braces mean in struct declaration?

Here is a cut-down definition of a

struct
, showing only the point at issue.

struct Entry {
// bookkeeping record for managing solution search
std::array<std::array<bool, DIM>, DIM> filled; // which holes have been filled
std::array<std::array<char, MAX>, MAX> cells; // individual cell entries, 0=empty
std::vector<Constraint> overlaps;
std::vector<Hole*>::iterator candidates;
Entry() = default;
};


This was actually a mistake. I was thinking that the default constructor would zero-initialize the arrays, but it just fills them with random garbage. I now know I need to write the default constructor, but I am confused by the behavior I ran across when testing.

This is a cut-down version of my test function:

void testEntry(void) {
Entry e;
std::cout << std::boolalpha;
e.cells[1][2] = 'a';
e.filled[0][0] = true;
for (int i = 0; i < MAX; ++i)
for (int j = 0; j < MAX; ++j)
std::cout<<i<<" "<<j<<" "<<e.cells[i][j]<<std::endl;
for (int i = 0; i < DIM; ++i)
for (int j = 0; j < DIM; ++j)
std::cout<<i<<" "<<j<<" "<<e.filled[i][j]<<std::endl;
}


When I ran this, the
filled
and
cells
arrays contained random garbage, and eventually I found my mistake. While debugging, I changed the declaration
Entry e;
to
Entry e{};
and the modified code appears to work as I intended, but I don't understand why.

I'm not quite able to follow the documentation. Under list initialization it says that, "If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed." This is pretty clear, but when I go to value initialization, I can't figure out which, if any, of the cases apply.
Is seems like this clause under zero-intialization is being applied
"If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored," but I don't see how to get here.

More than anything, I'm wondering if this behavior is actually defined in the specs, or if it might be different with a different compiler. (I'm using clang under Xcode 7.2.1).

Answer

What do empty brackets mean in struct declaration?

T object {}; is syntax for value initialization (4). Without the curly brackets, the object would be default initialized.

To be pedantic, this is not a "struct declaration". It is declaration of a variable.

when I go to value initialization, I can't figure out which, if any, of the cases apply.

This one applies:

2) if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor; (since C++11)

And that is how we get to zero initialization. Your interpretation of the zero initialization rules is correct.

I'm wondering if this behavior is actually defined in the specs

The rules in the linked pages are based on the standard, not on a specific implementation. The behaviour is defined.

Comments