Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code work in Clang++ but not G++?

Consider the following code:

struct Foo
{
    int x, y;

    Foo() = default;
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
};

int main()
{
    Foo f1 {1, 2};
    Foo f2 = {1, 2};
}

Compiling with clang++ yields no errors:

$ clang++ --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
$ clang++ -std=c++11 -stdlib=libc++ -pedantic t.cpp -o out
...builds and runs fine...

However, compiling with g++ 4.8.1 through ideone gives errors:

prog.cpp: In function ‘int main()’:
prog.cpp:12:17: error: no matching function for call to ‘Foo::Foo(<brace-enclosed initializer list>)’
     Foo f1 {1, 2};
                 ^
prog.cpp:12:17: note: candidate is:
prog.cpp:5:5: note: Foo::Foo()
     Foo() = default;
     ^
prog.cpp:5:5: note:   candidate expects 0 arguments, 2 provided
prog.cpp:13:19: error: could not convert ‘{1, 2}’ from ‘<brace-enclosed initializer list>’ to ‘Foo’
     Foo f2 = {1, 2};
                   ^

If I remove Foo(const Foo&) = delete; then it compiles fine in g++4.8.1.

Is there an error in my code that one compiler is ignoring but the other is not?

like image 370
Cornstalks Avatar asked Aug 13 '13 18:08

Cornstalks


1 Answers

C++11 8.5.1 [dcl.init.aggr] p1 defines aggregate types:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

user-provided is defined in 8.4.2 [dcl.fct.def.default] p4:

... A special member function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration.

Foo has two user-declared constructors, both of which are explicitly defaulted or deleted on their first declaration, so Foo is an aggregate.

GCC is wrong.

EDIT: This is in fact GCC bug 52707.

like image 109
Casey Avatar answered Nov 14 '22 17:11

Casey