Where did I get this idea?
It's apparently a relatively common misconception, as I've heard the same thing from a number of other people recently. Perhaps you picked it up from somebody else with this wrong idea, or perhaps the idea is just 'intuitive'.
{}
Initialization has worked as it does at least as far back as C89. I'm not aware of it ever working differently, or any compilers that ever did it differently.
For initializer lists when initializing an aggregate type (like an array):
If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from an empty initializer list (8.5.4). — Aggregates [dcl.init.aggr] 8.5.1p7
In C++ terms, when you use an empty initializer the object is value-initialized.
To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a
user-provided 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 (possibly cv-qualified) non-union class type without a
user-provided constructor, then the object is zero-initialized and, if
T’s implicitly-declared default constructor is non-trivial, that
constructor is called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
— Initializers [dcl.init] 8.5p7