The example code is:
#include <iostream>
using std::cout;
using std::endl;
void bar(double *) {
cout << "call bar()" << endl;
}
using Bar = void(*)(double *);
template <Bar pfunction>
void foo() {
// when call "foo<bar>()", there is a warning:
// the address of ‘void bar(double*)’ will never be NULL [-Waddress]
if (nullptr != pfunction) {
pfunction(nullptr);
}
cout << "shit" << endl;
}
int main() {
foo<nullptr>(); // OK
foo<bar>(); // warning
return 0;
}
from gcc manual:
-Waddress
Warn about suspicious uses of memory addresses. These include using the address of a function in a conditional expression, such as "void func(void); if (func)", and comparisons against the memory address of a string literal, such as "if (x == "abc")". Such uses typically indicate a programmer error: the address of a function always evaluates to true, so their use in a conditional usually indicate that the programmer forgot the parentheses in a function call.
The last sentence misunderstands my meaning. As in the code, it's necessary to test whether the function pointer is nullptr
. Should I add -Wno-address
or modify my code to silence the warning?
Update on 2015.9.15. As @SergeyA says, I use template specialization, and all work well.
template <Bar pfunction>
void foo() {
pfunction(nullptr);
cout << "shit" << endl;
}
template <>
void foo<nullptr>() {
cout << "shit" << endl;
}
Because this is compile-time code, in this template instantiation Bar will never be null - there is only one value for this. You should not mix compile-time programming with dynamic branching. To achieve your goal (not that I understand why you want your Bar to be template argument) you need to have a specialization of your foo for nullptr.
来源:https://stackoverflow.com/questions/32166386/g-waddress-may-misunderstand-my-meaning