Boost logo

Boost :

Subject: Re: [boost] [config] Proposed BOOST_NOEXCEPT_NOTHROW macro
From: Beman Dawes (bdawes_at_[hidden])
Date: 2012-08-29 07:40:56


On Tue, Aug 28, 2012 at 6:27 PM, Vicente J. Botet Escriba
<vicente.botet_at_[hidden]> wrote:
> Le 28/08/12 23:22, Beman Dawes a écrit :
>
>> The three current BOOST_NOEXCEPT* macro variants miss the case where
>> C++03 code has a "throw()" throw-specifier. Classes that derive from
>> standard library exceptions need this to avoid breaking code on C++03
>> compilers.
>>
>> I'm not enamored with the BOOST_NOEXCEPT_NOTHROW name, so feel free to
>> offer suggestions for alternate names.
>>
>> Here is the full set of macros:
>>
>> #ifdef BOOST_NO_NOEXCEPT
>> # define BOOST_NOEXCEPT
>> # define BOOST_NOEXCEPT_NOTHROW throw() <---- new macro
>> # define BOOST_NOEXCEPT_IF(Predicate)
>> # define BOOST_NOEXCEPT_EXPR(Expression) false
>> #else
>> # define BOOST_NOEXCEPT noexcept
>> # define BOOST_NOEXCEPT_NOTHROW noexcept <---- new macro
>> # define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate))
>> # define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression))
>> #endif
>>
>> Unless there are objections, I'll commit the changes Wednesday
>> afternoon Eastern US time.
>>
> I have no major problem with the additional macro BOOST_NOEXCEPT_NOTHROW ,
> but I don't see why it should be committed so quickly.

No real need, just wanting to clear it off my "half-done" list. (With
Git, I could just stash my changes, but that's a bit of a pain with
subversion.)

> I will cal it BOOST_NOEXCEPT_OR_NOTHROW.

I considered that, but was put off by its length.
BOOST_NOEXCEPT_OR_NOTHROW is clearer and the transition from throw()
to noexcept is confusing, so let's got with BOOST_NOEXCEPT_OR_NOTHROW

>
> My question is what macro will you use you implement noexcept in
> Boost.System. If you don't want to break c++03 compilers I think it should
> be BOOST_NOEXCEPT. Could you confirm?

Anything currently decorated with throw() has to use BOOST_NOEXCEPT_OR_NOTHROW.

#include <stdexcept>
 class my_error : public std::runtime_error
 {
 public:
   const char* what() const throw()
   {
     return "bingo";
   }
 };

For a C++03 compiler, replacing the throw() with BOOST_NOEXCEPT is
equivalent to removing it.

gcc 4.7 in C++03 mode will report an error:

c:\mingw\4.7\bin\../lib/gcc/mingw32/4.7.0/include/c++/stdexcept:127:5:
error: overriding
 'virtual const char* std::runtime_error::what() const throw ()'

Even for compilers that don't report this as an error, it is a silent
change in semantics that can be avoided by using
BOOST_NOEXCEPT_OR_NOTHROW.

For example, class system_error has three signatures that need
noexcept for C++11. All three of these are currently marked throw(),
so all three have to be replaced with BOOST_NOEXCEPT_OR_NOTHROW.

--Beman


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