Boost logo

Boost :

Subject: Re: [boost] [system] Add noexcept to conform with C++11
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2012-12-10 09:27:19


Beman Dawes wrote
> On Mon, Dec 10, 2012 at 2:44 AM, Christopher Kohlhoff
> <

> chris@

> > wrote:
>> Hi Beman, Vicente,
>>
>> On Mon, Dec 10, 2012, at 01:03 AM, Beman Dawes wrote:
>>> We need to contact Chris Kohlhoff to coordinate any asio changes with
>>> him. I have a vague recollection that he maintains the asio codebase
>>> elsewhere, so boost trunk is really just a mirror of some other repo.
>>> But I could be wrong about that.
>>
>> Beman is correct. A change made to the boost tree only is liable to get
>> clobbered. Vicente, if you don't mind can you please raise a ticket so
>> that I can coordinate the changes to asio properly.
>>
>>> That seems a lot worse than the noisy compiler error that will happen
>>> if user code just broke. How many folks are using a compiler that
>>> supports C++11 noexcept, have C++11 turned on, and are deriving from
>>> boost::system_error? Or am I missing other cases where user code would
>>> break?
>>
>> The main problem is that this change breaks user-defined error
>> categories. These definitely exist in the wild, some in projects that
>> use C++11. These uses are currently perfectly valid.
>>
>> If I understand correctly, a virtual function on a derived class is
>> permitted to have a more restrictive exception specification than that
>> on the base class. This should permit the following approach, which may
>> be more gentle on users:
>
> That's also my understanding, but I've never actually tried it with a
> real C++11 compiler.

I don't know what the C++ standard says, but at least MSVC 10.0, gcc-4.7.2
and gcc-4.8.0 complain when I define a virtual function as noexept when the
original declaration was not noexcept.

    class future_error_category :
      public boost::system::error_category
    {
    public:
        virtual const char* name() const BOOST_NOEXCEPT;
        virtual std::string message(int ev) const;
    };

Note that this behavior was the reason I created the ticket for
Boost.SysteM.

==================
d:\boost\trunk\boost/thread/future.hpp(383) : warning C4913: user defined
binary operator ',' exists but no overload could convert all operands,
default built-in binary operator ',' used
..\..\..\libs\thread\src\future.cpp(27) : error C2761: 'const char
*boost::thread_detail::future_error_category::name(void) const' : member
function redeclaration not allowed
..\..\..\libs\thread\src\future.cpp(28) : error C2447: '{' : missing
function header (old-style formal list?)

==================
gcc.compile.c++
..\..\..\bin.v2\libs\thread\build\gcc-mingw-4.7.2x\debug\threading-multi\future.o
..\..\..\libs\thread\src\future.cpp:27:41: error: declaration of 'virtual
const char* boost::thread_detail::future_error_category::name() const'
outside of class is not definition [-fpermissive]
===========
gcc.compile.c++
..\..\..\bin.v2\libs\thread\build\gcc-mingw-4.8.0x\debug\threading-multi\future.o
..\..\..\libs\thread\src\future.cpp:27:41: error: declaration of 'virtual
const char* boost::thread_detail::future_error_category::name() const'
outside of class is not definition [-fpermissive]
===========

So the Chris proposal doesn't works.

>> - Document the non-noexcept forms in boost.system as deprecated.
>>
>> - Define BOOST_SYSTEM_NOEXCEPT in terms of BOOST_SYSTEM_NO_DEPRECATED:
>>
>> #ifndef BOOST_SYSTEM_NOEXCEPT
>> # ifdef BOOST_SYSTEM_NO_DEPRECATED
>> # define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
>> # else
>> # define BOOST_SYSTEM_NOEXCEPT
>> # endif
>> #endif
>>
>> - Exclusively use the BOOST_SYSTEM_NOEXCEPT define in boost.system.
>>
>> - Use the non-conditional BOOST_NOEXCEPT on error_category-derived
>> classes elsewhere in boost. This is ok because BOOST_NOEXCEPT will
>> always be the same as or a more restrictive than BOOST_SYSTEM_NOEXCEPT.
>>
>> - After a couple of releases remove the test for
>> BOOST_SYSTEM_NO_DEPRECATED in defining BOOST_SYSTEM_NOEXCEPT.
>
> So after removal the BOOST_SYSTEM_NOEXCEPT define would look like this:?
>
> #ifndef BOOST_SYSTEM_NOEXCEPT
> # define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
> #endif

I would say that after the deprecation period the definition should be
   # define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
as the user should not be able to comeback.

>> This means that:
>>
>> - User code is not immediately broken. The usual process of deprecation
>> grants them a transitional period. (If some users choose to ignore the
>> deprecation notice then that's their problem.)
>>
>> - Users may define BOOST_SYSTEM_NO_DEPRECATED to ensure that their code
>> is forwardly compatible.
>>
>> I would certainly prefer something like this over immediate breakage.
>
> Vicente, this sound good to me, but:

If we prefer to avoid the break with BOOST_SYSTEM_NO_DEPRECATED, the boost
libraries should use BOOST_SYSTEM_NOEXCEPT or check
BOOST_SYSTEM_NO_DEPRECATED.

> * The change needs to include doc updates, and is generally complex
> enough that I'd like to review a diff of your changes before you
> commit them to trunk.
>
> * The release notice needs to have a Boost.System entry notifying
> users of the changes.

I would not make modification on your docs as they are written using html
directly. I will post here the text.

> * We need to test the changes both with and without
> BOOST_SYSTEM_NO_DEPRECATED to make sure they work as expected.

I don't know how to add regression tests with and without the definition of
BOOST_SYSTEM_NO_DEPRECATED. This would imply the construction of two
different boost_system library. I can of course make some local test
changing defining BOOST_SYSTEM_NO_DEPRECATED explicitly.

> * We need to mark our personal calendars for, say, six months out to
> be sure to make the BOOST_SYSTEM_NO_DEPRECATED change.

Yes I think that 2 releases should be enough for the deprecation period.

> Marshall, once the end of the transition period reached, this approach
> should address your concern about standards conformance if I
> understand it correctly.

So resuming we can

- define BOOST_SYSTEM_NOEXCEPT as follows

   # ifdef BOOST_SYSTEM_USES_NOEXCEPT
   # define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT
   # else
   # define BOOST_SYSTEM_NOEXCEPT
   # endif

An Boost installer administrator could force the use of noexcept by defining
BOOST_SYSTEM_USES_NOEXCEPT on his build.

- Use the conditional BOOST_SYSTEM_NOEXCEPT on error_category-derived
classes elsewhere in boost.

- After a couple of releases remove the test for BOOST_SYSTEM_NO_DEPRECATED
in defining BOOST_SYSTEM_NOEXCEPT.

   # define BOOST_SYSTEM_NOEXCEPT BOOST_NOEXCEPT

- Users inheriting from error_category-derived could move to use directly
BOOST_NOEXCEPT without breaking.

Best,
Vicente

--
View this message in context: http://boost.2283326.n4.nabble.com/system-Add-noexcept-to-conform-with-C-11-tp4639668p4639786.html
Sent from the Boost - Dev mailing list archive at Nabble.com.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk