[cfe-dev] C++11 error about initializing explicit constructor with {} ?

Richard Smith richard at metafoo.co.uk
Fri Jan 18 11:08:29 PST 2013


On Fri, Jan 18, 2013 at 10:39 AM, James Dennett <james.dennett at gmail.com> wrote:
> On Fri, Jan 18, 2013 at 8:32 AM, Benjamin Redelings
> <benjamin.redelings at duke.edu> wrote:
>> On 01/18/2013 05:01 AM, James Dennett wrote:
>>>
>>> On Fri, Jan 18, 2013 at 1:49 AM, Csaba Raduly <rcsaba at gmail.com> wrote:
>>>>
>>>> Hi Benjamin,
>>>>
>>>> On Thu, Jan 17, 2013 at 10:52 PM, Benjamin Redelings
>>>> <benjamin.redelings at duke.edu> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>>      I'm trying to compile some of my C++11 code under clang-3.2; I
>>>>> originally wrote it under g++.  This is a case where g++-4.8 (snapshot)
>>>>> accepts my code, but clang-3.2 does not.  The error message is:
>>>>>
>>>>> In file included from ../../../master/src/mcmc/moves.C:20:
>>>>> In file included from ../../../master/src/mcmc/sample.H:26:
>>>>> ../../../master/src/mcmc/mcmc.H:390:94: error: chosen constructor is
>>>>> explicit in copy-initialization
>>>>>      std::set<int> get_affected_parameters(const
>>>>> owned_ptr<Probability_Model>&) const {return {};}
>>>>> ^~
>>>>> /usr/include/c++/v1/set:378:14: note: constructor declared here
>>>>>      explicit set(const value_compare& __comp = value_compare())
>>>>>
>>>>>
>>>>> So, basically, this code is trying to initialize a std::set<int> with
>>>>> {}.
>>>>> I'm not sure clang is right here, but I'm also not sure is wrong.  Can
>>>>> someone tell me, so I can possibly submit a bug report?
>>>>
>>>> Maybe it's already fixed. The following code:
>>>>
>>>> #include <set>
>>>> std::set<int> getset() { return {}; }
>>>>
>>>> is compiled without errors by
>>>>
>>>> $ clang++ -v --std=c++0x setinit.cc
>>>> clang version 3.3 (trunk 172707)
>>>> Target: x86_64-unknown-linux-gnu
>>>> Thread model: posix
>>>
>>> You may be compiling against libstdc++, which has a C++11-compliance
>>> bug in that its default constructor for set is not explicit (while the
>>> standard specifies that it should be), which would make this compile
>>> when it should not.
>>>
>>> (On the other hand, I'm not sure that the standard _meant_ to specify
>>> that, or if it was just an accident.  Turning {} into an empty set
>>> seems like a rather pretty thing.)
>>>
>>> -- James
>>
>> I don't think the issue is the standard library, and I'm not sure its fixed
>> in clang 3.3.  I checked these combinations:
>>
>> clang, libstdc++: yes
>> clang, libstdc++ modified to reflect the standard: NO
>> clang, libc++: NO
>
> Thanks for running these tests.  The results above are consistent with
> Clang being correct...
>
>> gcc, libstdc++: yes
>> gcc, libstdc++ modified to reflect the standard: yes.
>
> ...and GCC being buggy.
>
>> Here "modifed to reflect the standard" means removing the constructor
>> set::set(), and adding a default argument to the constructor
>> explicit set(const _Compare& __comp, const allocator_type& __a =
>> allocator_type())
>>     to yield
>> explicit set(const _Compare& __comp=_Compare(), const allocator_type& __a =
>> allocator_type())
>>
>> So, it seems that libstdc++ is indeed wrong, but g++ accepts {} even when
>> libstdc++ is fixed.
>
> Right; libstdc++ and GCC are both buggy.

I reported the libc++ / libstdc++ part of this as a defect a few months ago:

http://cplusplus.github.com/LWG/lwg-active.html#2193



More information about the cfe-dev mailing list