[cfe-dev] Inheriting from std::error_category with libc++

Howard Hinnant hhinnant at apple.com
Wed Sep 26 08:42:24 PDT 2012


On Sep 26, 2012, at 11:28 AM, Michael van der Westhuizen <r1mikey at gmail.com> wrote:

> 
> On 26 Sep 2012, at 5:17 PM, Howard Hinnant <hhinnant at apple.com> wrote:
> 
>> On Sep 26, 2012, at 11:02 AM, Howard Hinnant <hhinnant at apple.com> wrote:
>> 
>>> On Sep 26, 2012, at 9:49 AM, Michael van der Westhuizen <r1mikey at gmail.com> wrote:
>>> 
>>>> Hi All,
>>>> 
>>>> I've come across what I believe is a problem in libc++.
>>>> 
>>>> While working through Chris Kohlhoff's blog entries about system_error (http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-4.html) I discovered that it's not possible to inherit from std::error_category in libc++.
>>>> 
>>>> The following small test case compiles correctly under G++ 4.6.3 on Linux with libstdc++, but fails under Mac OS X Mountain Lion with Xcode 4.5 (Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)).
>>>> 
>>>> #include <system_error>
>>>> #include <string>
>>>> 
>>>> namespace {
>>>> class test_category_impl
>>>> : public std::error_category
>>>> {
>>>> public:
>>>> virtual const char * name() const noexcept
>>>> {
>>>>     return "test_category";
>>>> }
>>>> virtual std::string message(int ev) const
>>>> {
>>>>     return "default";
>>>> }
>>>> };
>>>> }
>>>> 
>>>> const std::error_category & test_category()
>>>> {
>>>> static test_category_impl inst;
>>>> return inst;
>>>> }
>>>> 
>>>> 
>>>> 
>>>> With G++ on Linux I'm compiling with:
>>>> g++ -c -std=c++0x -o bugtest.o bugtest.cpp
>>>> 
>>>> This works as expected.
>>>> 
>>>> With clang on the Mac I'm compiling with:
>>>> clang++ -c -std=c++11 -stdlib=libc++ -o bugtest.o bugtest.cpp
>>>> 
>>>> This gives the following error:
>>>> $  clang++ -c -std=c++11 -stdlib=libc++ -o bugtest.o bugtest.cpp
>>>> bugtest.cpp:22:31: error: call to implicitly-deleted default constructor of '<anonymous>::test_category_impl'
>>>> static test_category_impl inst;
>>>>                           ^
>>>> bugtest.cpp:5:7: note: 'test_category_impl' defined here
>>>> class test_category_impl
>>>>   ^
>>>> 1 error generated.
>>>> 
>>>> All literature I've come across indicates that I should be able to inherit from error_category and the wording in the draft of N3242 states "Classes may be derived from error_category to support categories of errors in addition to those defined in this International Standard."  The libc++ implementation seems quite deliberate in its intent to not allow the user to inherit this class (it uses a private default constructor and a private friend class called __do_message internally within the library).
>>>> 
>>>> So have things changed? Are we no longer intended to be able to create error_category subclasses, or is this a bug?
>>> 
>>> This looks like a standards bug.  I filed a LWG issue on it here:
>>> 
>>> http://cplusplus.github.com/LWG/lwg-active.html#2145
>>> 
>>> but the lwg has not yet commented on the issue.  Generally my policy is to wait until the lwg addresses the issue before changing the libc++ implementation.  But in this case I'm tempted to go ahead and fix this in anticipation of the lwg accepting the issue as proposed.
>>> 
>>> Does anyone have any /objections/ to me pushing this fix in now (as proposed in http://cplusplus.github.com/LWG/lwg-active.html#2145)?
>> 
>> Oh, never mind.  It appears I *already* did that:   :-)
>> 
>> -----------------------
>> r153194 | hhinnant | 2012-03-21 12:18:57 -0400 (Wed, 21 Mar 2012) | 1 line
>> 
>> It appears that the standard accidentally removed the default constructor for error_category.  I'm putting it back in.  This fixes http://llvm.org/bugs/show_bug.cgi?id=12321.
>> -----------------------
>> 
> 
> Any chance you could bump _LIBCPP_VERSION so that I can detect this?  I'm currently doing a heinous "#define private protected" hack in my implementation file, and I'd prefer not to :-)

Done.

Howard

> 
> Michael
> 
>> On Sep 26, 2012, at 11:11 AM, Michael van der Westhuizen <r1mikey at gmail.com> wrote:
>> 
>>> This looks like exactly what I'm experiencing.  As an aside, the libstdc++ folks have declared the default constructor as protected, which might be a better choice.
>> 
>> Hmm... that's the danger of moving ahead of the committee. :-\
>> 
>> Howard
>> 
> 




More information about the cfe-dev mailing list