From C++14
8.5.1 Aggregates [dcl.init.aggr]
1 An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or
protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
2 When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list
are taken as initializers for the members of the aggregate, in increasing subscript or member order.
This means that s.x is first initialized with 123, then s.y is initialized with s.x.
Without optimization, GCC 6.3 generates
C::C():
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8] # read address of s
mov DWORD PTR [rax], 123 # write 123 to s.x (offset 0 from s)
mov rax, QWORD PTR [rbp-8] # read address of s again
mov edx, DWORD PTR [rax] # read contents of s.x to edx
mov rax, QWORD PTR [rbp-8] # read address of s
mov DWORD PTR [rax+4], edx # write s.y (offset 4 from s)
nop
pop rbp
ret
Which agrees with what the standards says.
S
is trivial. Again, this rule seem to favor you. – Coussoule