g ++ -Waddress可能会误解我的意思

问题描述:

示例代码为:

#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;
}

来自gcc手册:

-地址

警告有关内存地址的可疑使用.其中包括在条件表达式中使用函数的地址,例如"void func(void); if(func)",以及与字符串文字的存储地址,例如"if(x =="abc")".这样的用法通常表示程序员错误:函数始终求值为true,因此在有条件的情况下使用它们通常表示程序员忘记了括号函数调用.

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.

最后一句误解了我的意思.与代码中一样,必须测试函数指针是否为 nullptr .我应该添加 -Wno-address 还是修改我的代码以使警告静音?

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?

于2015.9.15更新.正如@SergeyA所说,我使用模板专业化,并且一切正常.

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;
}

由于这是编译时代码,因此在此模板实例化中Bar永远不会为null-为此,只有一个值.您不应将编译时编程与动态分支混合使用.为了实现您的目标(不是我理解您为什么要将Bar用作模板参数),您需要对nullptr的foo进行专门化处理.

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.