On quarta-feira, 26 de julho de 2017 00:50:59 PDT Zhihao Yuan wrote:
> First, the motivation seems not strong enough to
> us. If the struct itself is already trivial, using the
> traditional value-init + assignment approach
>
> stat buf{};
> buf.atime = now;
> ...
It's not equivalent if I'm trying to have a static const variable.
By "initialization order", I was trying to mean "the order the
designated initializers are listed", not "the order the class' member
variables are initialized". Sorry for the misleading term.
What I tried to mean is that we can "repeat the mistake" and initialize
the object using the order its members are declared, regardless the
order the designated initializers are listed, and leaves the compiler to
warn the user if appropriate. We can also allow the user to suppress the
warning using some attribute on his will.
Still, even if it's a mistake for mem-init-clause, for the third party
structures whose definition cannot be controlled by us, the "severity of
the mistake" is mitigated.
struct Agg
{
int x, y;
};
Agg a{5, a.x};
On segunda-feira, 31 de julho de 2017 11:05:09 PDT Nicol Bolas wrote:
> Well, the C++ language doesn't work well with that, since members must be
> initialized in the order they're presented in the class definition. In C++,
> changing the order of members is not a backwards-incompatible change, and
> designated initializers will not change that.
Only because we say it is. There's nothing else preventing initialisation in
any order for trivial types.
Here's the question I have with list and aggregate initialization. Is this well-defined, currently:
struct Agg
{
int x, y;
};
Agg a{5, a.x};
In a braced-init-list, the initializing expressions are evaluated in the order they appear. So it could be that the initialization of `a.x` happens before the expression to start initializing `a.y`. If that is the case, then it's basically impossible to do this out-of-order. Even for trivial types, the initializers could depend on each other in very funky ways.
Personally, I hope that it is not well-defined.
My suggestion would be that designated initializers can be written in any order, but are executed in the order of the struct declaration. As an extra rule the compiler can (must?) check that members are not refered before they are initialized.I really dislike the idea of forcing users to write designated initializers in the same order as the struct declaration have them, not only as the library writer may change the order but more importantly that designated initializers are most useful when you have many members and only initialize a few with non-default values and remembering the order in this case is much harder than remembering the names.Are there other problems with allowing any order of designated initializers besides checking that not yet initialized members are not referred?
In my experience initiing one member from another is very rarely useful, so even if reordering the fields of the struct has a potential to cause compiler errors when compiling users of the struct I don't think this would case very many real problems. If this is the concern I would rather forbid refering to other members from initializers if there are any designators in the initializer.
On Mon, Jul 31, 2017 at 2:42 PM, Thiago Macieira <thi...@macieira.org> wrote:
> It definitely isn't for non-trivial types, but I don't
> know if it should be allowed for trivial ones.
>
> [...]
>
> Either way, that doesn't stop us from allowing:
>
> Agg a { .y = 5, .x = 5 };
>
I've stated my concern with dividing the feature
into trivial types only and those not -- it brings
damage when the library evolves.
However, I feel it's more acceptable if we allocate
a syntax to let people opt-in. I mean, what if
such a discrimination happens only when a
user asks for it by using the = { ... } initializer
(copy-init syntax)?
Well, the C++ language doesn't work well with that, since members must be initialized in the order they're presented in the class definition. In C++, changing the order of members is not a backwards-incompatible change, and designated initializers will not change that.
The <time.h> header shall declare the timespec structure, which shall include at least the following members:
time_t tv_sec Seconds. long tv_nsec Nanoseconds.
The proof that the rule was a mistake is that compilers warn about it. If it wasn't something worth warning people about, they wouldn't put the warning there. So there is clearly an intent that the writer of the constructor ought to put them in the right order.
But if you allow designated initializers to be specified out of member declaration order, it now stops on another "simple and universal rule":
Expression in braced-init-lists are sequenced in the order they appear
So, if you allow unordered designated initializers, which rule wins? Either the members will be initialized out of order, or the expressions will be evaluated out of order.