Search code examples
c++visual-c++gccc++11clang++

Default argument in out of class definition of constructor, gcc vs clang


Code looks like:

struct Foo {
    Foo(const char *);
};

Foo::Foo(const char *str = 0)
{
}

VS 2013 and gcc 4.8.0 accept such code, while clang 3.3 reject such code with:

error: addition of default argument on redeclaration makes this constructor a default constructor

who is right from standard (C++03 and C++11) point of view?

Note:

I like clang's choice too, but I going to report bug to gcc and visual studio, and if this is not correct from standard point of view, this helps to convince compiler's developers to fix this issue.

GCC

I described issue here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194

But no luck, they suspend bug fixing untill draft become standard. Demo


Solution

  • This has been discussed on the Clang mailinglist and has been submitted as a Defect Report Core Issue 1344.

    From the mailinglist discussion:

    The idea is that the presence of certain special members affects core properties of a class type, like whether it's POD or trivially copyable. Deciding these properties should not require whole-program knowledge; it's important for us to be able to deduce them just from the class definition. The really problematic case is turning a "normal" constructor into a copy or move constructor by adding default arguments, but IIRC introducing a default constructor was also problematic.

    The fix is that you should put the default argument in the initial declaration of the constructor.

    This was last discussed by WG21 at the Bloomington meeting. Notes from there:

    "Consensus: Make this ill-formed as suggested in the write-up. Core issue 1344. Priority 0, Doug drafting."

    So CWG has agreed (in principle) that this should be ill-formed.

    TL;DR Clang is right whenever the defect gets fixed (not sure if that can officially only happen with C++14, or if such Committee decisions can also be done retroactively on C++11)