为什么比较成员函数指针为NULL会产生警告?

Why does comparing a member function pointer to NULL generate a warning?

本文关键字:警告 NULL 比较 成员 函数 指针 为什么      更新时间:2023-10-16

以下代码在Windows, Mac和iOS上编译时没有警告:

class MyClass {
    SomeOtherClass * m_object;
    void (SomeOtherClass::*m_callback)();
public:
    MyClass(SomeOtherClass * _object,void (SomeOtherClass::*_callback)()=NULL) :
        m_object(_object),m_callback(_callback) {}
    void DoStuff() {
        //generates warning: NULL used in arithmetic when compiling with the Android NDK
        if (NULL==m_callback) {
            m_object->DoNormalCallback();
        } else {
            (m_object->*m_callback)();
        }
    }
};

为什么会产生这个警告,我能做些什么?

如果NULL被定义为((void*)0),您可能会得到一个警告。对象指针与函数指针的类型不兼容。使用普通的0代替NULL0是一个空指针常量,与函数指针和对象指针类型兼容。

EDIT对不起,我没有注意。这里有一个成员函数指针,而不仅仅是函数指针。与((void*)0)比较也是违反规则的,许多编译器会发出错误,而不仅仅是警告。

EDIT 2致所有注释的人:我知道一个符合标准的c++编译器不会将NULL定义为((void*)0)。问题是存在不兼容的编译器和损坏的第三方库(我都见过)。

我不认为你可以比较0(或NULL)与成员函数指针,特别是因为它们可能不是真正的指针(当函数是virtual时,例如)。

就我个人而言,我会重写if测试而不进行比较,例如:

void DoStuff() {
    if (m_callback) {
        (m_object->*m_callback)();
    } else {
        m_object->DoNormalCallback();
    }
}

并且,为了加分,在构造函数中执行此测试。

class MyClass {
    SomeOtherClass * m_object;
    void (SomeOtherClass::*m_callback)();
public:
    MyClass(SomeOtherClass * _object,void (SomeOtherClass::*_callback)()=NULL) :
        m_object(_object),m_callback(_callback)
    {
         // Use "DoNormalCallback" unless some other method is requested.
         if (!m_callback) {
             m_callback = &SomeOtherClass::DoNormalCallback;
         }
    }
    void DoStuff() {
        (m_object->*m_callback)();
    }
};

尝试使用-Wno-conversion-null关闭警告。

if (m_callback)是andr Caron建议的,但我从来都不是隐式强制转换为bool的粉丝,我更喜欢使用计算为bool的操作符。这有点啰嗦,但它可以工作:

if (static_cast<void (SomeOtherClass::*)()>(NULL)==m_callback)
    m_object->DoNormalCallback();   
} else {   
    (m_object->*m_callback)();   
}

仍然不确定为什么GCC的NDK版本需要强制转换。