In the following program the object A a is directly initialized from braced-init-list {A{}}:
#include <iostream>
struct A {
int v = 0;
A() {}
A(const A &) : v(1) {}
};
int main() {
A a({A{}});
std::cout << a.v;
}
MSVC and GCC print 0 here meaning that copy-elision takes place. And Clang prints 1 executing the copy-constructor.
Online demo: https://gcc.godbolt.org/z/1vqvf148z
Which compiler is right here?
I think that clang is right in using the copy constructor and printing
1for the reason(s) explained below.First note that
A a({A{}});is direct-initialization as can be seen from dcl.init#16.1:Now, dcl.init#17.6 is applicable here:
(emphasis mine)
This means that the copy constructor(which is the selected constructor here) will be used/called to initialize the object named
awith the expression-list as its argument and since in your copy ctor's member initializer list you're initializinga.vto1, the output printing1of clang is correct.