I realized that I can declare a type for a pointer to noexcept function via using, but I am forbidden such declaration if I use a typedef. Consider the code below:
#include <iostream>
using fptr = void(*)() noexcept;
// typedef void(*FPTR)() noexcept; // fails to compile
void f() noexcept
{
std::cout << "void f() noexcept" << std::endl;
}
void g()
{
std::cout << "void g()" << std::endl;
throw 10;
}
int main()
{
fptr f1 = f;
fptr f2 = g; // why can we do this?
try {
f1();
f2();
}
catch (...)
{
std::cout << "Exception caught" << std::endl;
}
}
If I uncomment the FPTR declaration, I'm getting
error: 'FPTR' declared with an exception specification
However, the using works just fine. Compiled with both gcc4.9 and gcc5.
My questions are:
using with noexcept since we can bind the pointer to functions not declared noexcept, as in the line fptr f2 = g;Seems to be a bug related to gcc, even gcc5 doesn't catch it. Filled a bug report
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65382
This seems to be a bug in GCC; Clang rejects both as exception specifications are not allowed in type aliases or typedefs. This can be found in:
15.4 Exception specifications [except.spec]
2 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.
[...]
The standard also explicitly says that both should be consistent:
7.1.3 The
typedefspecifier [dcl.typedef]2 A typedef-name can also be introduced by an alias-declaration. The identifier following the
usingkeyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. It has the same semantics as if it were introduced by thetypedefspecifier. In particular, it does not define a new type and it shall not appear in the type-id.
(emphasis mine)
To answer your second question: GCC probably just ignores the exception specification as functions can not be overloaded on just the exception specification - it is not part of the function's signature. This can be found here:
8.3.5 Functions [dcl.fct]
6 [...] The return type, the parameter-type-list, the ref-qualifier, and the cv-qualifier-seq, but not the default arguments (8.3.6) or the exception specification (15.4), are part of the function type. [ Note: Function types are checked during the assignments and initializations of pointers to functions, references to functions, and pointers to member functions. — end note ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With