Is knowledge about noexcept-ness supposed to be forwarded when passing around a function pointer?
c++, c++11, noexcept
Solution
In C++17, `noexcept` is finally added to the type system. A pointer to non-`noexcept` function cannot be implicitly converted to pointer to `noexcept` function. (But the other way around is permitted).
clang 3.9.0 with `-std=c++1z`, and g++ 7.0 with `-std=c++17`, reject the line `test3(f1);`.
Problem
I have written the following code to test `noexcept` propagation across function calls, and it seems that it doesn't work as I would have thought. In GCC 4.7.2, A function can effectively be tested against being `noexcept` only directly or when passed as a template specialization argument; but not when passed as an argument to a templated function, or as a function pointer to a normal function -- even when that function declares its formal parameter as being `noexcept`. Here's the code: ``` #include <iostream> #define test(f) \ std::cout << __func__ << ": " #f " is " \ << (noexcept(f()) ? "" : "not ") \ << "noexcept\n"; template <void(*f)()> static inline void test0() { test(f); } template <typename F> static inline void test1(F f) { test(f); } static inline void test2(void(*f)()) { test(f); } static inline void test3(void(*f)()noexcept) { test(f); } void f1() {} void f2() noexcept {} int main() { test(f1); test(f2); test0<f1>(); test0<f2>(); test1(f1); test1(f2); test2(f1); test2(f2); test3(f1); test3(f2); return 0; } ``` And here's output: ``` main: f1 is not noexcept main: f2 is noexcept test0: f is not noexcept test0: f is noexcept test1: f is not noexcept test1: f is not noexcept test2: f is not noexcept test2: f is not noexcept test3: f is not noexcept test3: f is not noexcept ``` Why is `noexcept`ness not propagated in other cases? In case of `test1`, the whole function is "instantiated" with the proper type of `F`, the compiler surely knows at that time whether F is a `noexcept` function. Why is it possible to write `test3` the way I wrote it, when the `noexcept`ness declaration is completely ignored? Does the standard have to say something specific about this?