Search code examples
c++c++11function-pointersnoexcept

How do I create an alias for a noexcept function pointer?


I'd like to do this:

using function_type = void (*)(void*)noexcept;

But I get an error "exception specifications are not allowed in type aliases." (clang in version 6.1 of Xcode)

Is there a workaround to create an alias with a noexcept specifier?

I'm looking for something that works as defined by the language (not an extension) for cross-platform capabilities.


Solution

  • The standard explicitly forbids an exception specification from appearing in a typedef or an alias declaration. But it also states that the exception specifier may appear in a function pointer type.

    §15.4/2 [except.spec]

    An exception-specification shall appear only on a function declarator for a function type, pointer to function type, reference to function type, or pointer to member function type that is the top-level type of a declaration or definition, or on such a type appearing as a parameter or return type in a function declarator. An exception-specification shall not appear in a typedef declaration or alias-declaration.

    And if a pointer to function does have an exception specification, then that function pointer must always be assigned a function type that has a compatible exception specification.

    §15.4/5

    ... A similar restriction applies to assignment to and initialization of pointers to functions, pointers to member functions, and references to functions: the target entity shall allow at least the exceptions allowed by the source value in the assignment or initialization. ...

    Using these two, you can get the noexcept specification into the function pointer type in a roundabout fashion.

    void (*foo_ptr)(void *) noexcept = nullptr;
    using function_type = decltype(foo_ptr);
    

    Now, you cannot assign a function without a noexcept(true) specification to a function pointer of type function_type. clang will fail to compile the code with the error

    error: target exception specification is not superset of source