|
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