C++ Logo

std-proposals

Advanced search

Re: [std-proposals] noexcept(static)

From: Bingzhi <bingzhi2025_at_[hidden]>
Date: Fri, 4 Sep 2026 23:25:08 +0800 (CST)
Nice feature!
I have some questions:
Should it be SFINAE-friendly? Like, I would use:
namespace force_safe { template <class Container> constexpr auto size(const Container& x) noexcept(static) { return x.size(); } }
template <class Container> concept safe_size_usable = requires (Container& x) { fore_safe::size(x); };


Should it matter in function template overloading? I'd like to write:
namespace optimized_versions
{
  template <class Book> void reorder(Book& b) noexcept(static) { ... } // optimized noexcept version
  template <class Book> void reorder(Book& b) noexcept(false) { try { ... } catch (...) { ... } }
}
instead of writing ``requires requires { { ... } noexcept; }`` constraints for that noexcept version.


>Date: Fri, 4 Sep 2026 11:51:09 +0100
>From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
>To: std-proposals <std-proposals_at_[hidden]>
>Subject: [std-proposals] noexcept(static)
>Message-ID:
> <CALtZhhNhi8w=TOKDz5Q41v9_ji_7kxvMDkcaiU3pe1Q2MHgmKA_at_[hidden]>
>Content-Type: text/plain; charset="UTF-8"
>
>If you mark a function as 'noexcept(false)', it is free to throw an
>exception up to its caller.
>
>If you mark a function as 'noexcept' or 'noexcept(true)', it will
>never throw an exception up to its caller -- but only because
>'std::terminate' gets called instead.
>
>If you mark a function as 'noexcept(static)', it will never throw an
>exception up to its caller -- because you'll get a compile-time error
>if any statement inside the function body might throw.
>
>In C++, when including a header from a C file, you usually do:
>
> extern "C" {
> #include "someClibrary.h"
> }
>
>but now you can also do:
>
> extern "C" noexcept(static) {
> #include "someClibrary.h"
> }
>
>This has the effect of sticking "noexcept(static)" on all functions
>and all function pointers. And just in case you're worried about
>nesting, you can turn off the nesting as follows, look closely for the
>exclamation point:
>
> extern "C" noexcept(static) {
> #include "someClibrary.h"
> extern "C++" !noexcept(static) {
> #include "someCPlusPluslibrary.hpp"
> }
> }
>
>Here's where I would use this new feature:
> (1) I would consistently mark destructors as 'noexcept(static)' --
>as you don't want an exception being thrown while the stack is being
>unwound.
> (2) When writing C++ code that uses a C library, you want to make
>sure all resources get freed, because you don't want an exception to
>be thrown between "OpenResource" and "CloseResource".
> (3) When calling a C++ function from C -- just for a little added
>assurance that std::terminate won't get called.
> (4) On move-constructors and move-assignment operators. These get
>marked 'noexcept' so that vector reallocation takes the 'move' path,
>but you want to be sure that std::terminate doesn't get called.
> (5) On a coroutine promise's 'final_suspend'. The standard already
>requires that 'co_await promise.final_suspend()' not be
>potentially-throwing, so the compiler forces you to mark it 'noexcept'
>-- but that check is on the declaration, not on the body.
>'noexcept(static)' is what actually verifies it.
>
>Here it is tested and working:
>
> https://godbolt.org/z/hE3e13Pvq
>
>Here's the compiler patch:
>
> https://github.com/healytpk/gcc-thomas-healy/commit/noexcept_static
>
>And here's the GodBolt copy-pasted:
>
> #include <new>
>
> void Func1(void) noexcept(static)
> {
> new int[64]; // fail to compile
> }
>
> void Func2(void) noexcept(static)
> {
> new(std::nothrow) int[64];
> }
>
>
> int main(void)
> {
> Func1();
> Func2();
> }

Received on 2026-09-04 15:25:22