[cfe-dev] [bug?] list-initialization failures in a return statement

Jim Porter jvp4846 at g.rit.edu
Thu Aug 21 17:26:24 PDT 2014


On 8/21/2014 4:00 PM, Richard Smith wrote:
> On Mon, Aug 18, 2014 at 8:59 AM, Jim Porter <jvp4846 at g.rit.edu
> <mailto:jvp4846 at g.rit.edu>> wrote:
>
>     I've found what I think are a couple of bugs in how clang (3.4)
>     list-initializes objects in a return statement. It probably applies
>     to any copy-list-initialization context, but I haven't tested all
>     the possibilities. I'm posting this here instead of just filing a
>     bug because I wanted to get some feedback on whether I'm correct
>     about this or not.
>
>     --------------------
>
>     First, I think clang is incorrectly failing on the explicit default
>     constructor in this sample:
>
>        struct foo {
>          explicit foo() {}
>        };
>
>        foo make_foo() {
>          return {};
>        }
>
>        int main() {
>          auto f = make_foo();
>          return 0;
>        }
>
>     clang tells me "chosen constructor is explicit in
>     copy-initialization", but according to 8.5.4p3, make_foo should be
>     value-initializing foo:
>
>        If the initializer list has no elements and T is a class type with a
>        default constructor, the object is value-initialized.
>
>
> OK, but value-initialization defers to default-initialization here, and
> default-initialization performs overload resolution to select the
> default constructor. This -- presumably -- uses 13.3.1.7 to select the
> constructor:
>
> "When objects of non-aggregate class type T are list-initialized
> (8.5.4), overload resolution selects the constructor in two phases:
>   -- [choose from initializer-list constructors]
>   -- [try all constructors]
> If the initializer list has no elements and T has a default constructor,
> the first phase is omitted. In copy-list-initialization, if an explicit
> constructor is chosen, the initialization is ill-formed."
>
> Since we're in copy-list-initialization, T has a default constructor,
> and the list has no elements, we try all constructors. Since we pick an
> explicit constructor, the program is ill-formed.

Hmm. Does this mean it's impossible to write a function that constructs 
an arbitrary DefaultConstructible object? I had hoped to do something like

   template<typename T>
   T make() {
     return {};
   }

so that I could construct non-movable objects, but I guess that won't 
work for objects with explicit default constructors. It seems like clang 
is indeed doing the right thing, so perhaps this is an issue to bring up 
with the standards committee...

- Jim




More information about the cfe-dev mailing list