Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 noexcept qualifier and inline methods

Does C++11 give any guarantees about inline functions or methods, when they make calls to other functions declared with the noexcept qualifier?

class My_String { ...

    const char * c_str () const noexcept;
    inline operator const char * () const { return c_str(); }
};

I assume an optimizing compiler would be free to implement the inline method without full EH and stack unwinding, as per the noexcept qualification. I would also expect this for a simple accessor method too:

... inline operator const char * () const { return m_buffer; }

While this example looks trivial, exception guarantees matter when used to implement other classes or functions. Q: Does the C++11 standard address this or should inline methods be marked noexcept? Or is it better to omit noexcept unless required to match a class or function specification?

Edit: To avoid some confusion: Is noexcept implicit for the inline method?

like image 217
Brett Hale Avatar asked Aug 15 '12 11:08

Brett Hale


People also ask

What is the C ++ 11 meaning of the term Noexcept?

noexcept specifier(C++11) specifies whether a function could throw exceptions. Dynamic exception specification(until C++17) specifies what exceptions are thrown by a function (deprecated in C++11)

When should you use Noexcept?

E. 12: Use noexcept when exiting a function because of a throw is impossible or unacceptable. you don't care in case of an exception. You are willing to crash the program because you can not handle an exception such as std::bad_alloc due to memory exhaustion.

Is Noexcept required?

Explicit instantiations may use the noexcept specifier, but it is not required. If used, the exception specification must be the same as for all other declarations.

Does Noexcept make code faster?

That noexcept keyword is tricky, but just know that if you use it, your coding world will spin faster.


1 Answers

Sorry, no. The only implicit exception-specifications are

  • On destructors.
  • On other implicitly declared or explicitly defaulted special member functions: default constructors, copy and move constructors, and copy and move assignment, when not declared in a class definition, or declared with = default;.
  • On deallocation functions: operator delete and operator delete[].

[Note that for deallocation functions, an implicit exception-specification is always as if noexcept(true). For all destructors, and for special member functions which are implicitly declared or explicitly defaulted on the first declaration, the implicit exception-specification can be either noexcept(true) or noexcept(false), as determined from the exception-specifications of the corresponding special member functions of any base classes and members of class type.]

So with either example declaration, noexcept(static_cast<const char*>(std::declval<const MyString>())) must be false. Go ahead and write noexcept where it might matter.

Of course, as you noted, a compiler optimization is still allowed to notice an inline function can't throw exceptions and simplify exception handling in the caller.

like image 178
aschepler Avatar answered Oct 05 '22 09:10

aschepler