Is knowledge about noexcept-ness supposed to be forwarded when passing around a function pointer?

对着背影说爱祢 提交于 2019-12-23 09:28:10

问题


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 noexceptness 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 noexceptness declaration is completely ignored?

Does the standard have to say something specific about this?


回答1:


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);.




回答2:


Section 15.4.13 of the C++11 standard states that "an exception-specification is not considered part of a function's type".



来源:https://stackoverflow.com/questions/14003502/is-knowledge-about-noexcept-ness-supposed-to-be-forwarded-when-passing-around-a

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!