I'm using the standard function wrapper from the C++11 library, and I am seeing some strange behavior with its boolean operator. If I create a std::function
object the boolean operator returns false. This is still true if I assign nullptr
to the object and check again. The problem appears when I assign it a void pointer which I have cast into a function pointer. Consider the following program:
#include <functional>
#include <iostream>
void* Test() {
return nullptr;
}
int main(int argc, char* argv[]) {
std::function<void()> foo;
std::cout << !!foo << std::endl;
foo = nullptr;
std::cout << !!foo << std::endl;
foo = reinterpret_cast<void(*)()>(Test());
std::cout << !!foo << std::endl;
return 0;
}
What I expect as output is 0 0 0
but the result is 0 0 1
(see demo). Can anyone explain why the boolean operator returns true when it contains a null, non-callable function pointer? And please also mention a workaround to check for nullptr
in std::function
NOTE: I've already tried checking if the target is null (with foo.target<void*>() == nullptr
) instead of using the boolean operator, but it seems as if no matter what the function object contains, the target is always null (even when the function object is perfectly fine with being called).
I don't think the code is doing what you think it does. This line:
means that you receive a
void*
fromTest()
. You then procede toreinterpret_cast
this pointer-to-object into a pointer-to-function. This is not allowed and therefore the code yields undefined behavior and therefore any output of the compiler is valid.The relevant parts of the standard are
and
(emphasis mine)
Here's a reduced test case taking
std::function
(and its possible bugs) out of the equation:Live example
Looks like a bug to me. First, here's a simplified example that doesn't play any games with casts:
It still prints 1 with GCC. It shouldn't: