以下位代码在没有警告的情况下编译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)();
}
}
};
为什么会产生警告,我该怎么办呢?
答案 0 :(得分:4)
如果NULL
定义为((void*)0)
,您可能会收到警告。对象指针与函数指针不是类型兼容的。使用普通0
代替NULL
。 0
是一个与函数指针和对象指针类型兼容的空指针常量。
编辑抱歉,我没有给予适当的关注。这里有一个成员函数指针,而不仅仅是一个函数指针。将((void*)0)
与((void*)0)
进行比较也违反规则,许多编制者将在此处发出错误,而不仅仅是警告。
EDIT 2 致所有评论者:我知道符合标准的C ++编译器不会将NULL定义为{{1}}。问题是存在不合格的编译器和破坏的第三方库(我已经看过两者)。
答案 1 :(得分:2)
我认为您不允许将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)();
}
};
答案 2 :(得分:1)
尝试使用-Wno-conversion-null
关闭警告。
答案 3 :(得分:1)
在C ++ 11之前,将指向成员的指针与'0'进行比较的结果是未定义的。
在C ++ 11中,将指向成员的指针与新的C ++ 11关键字'nullptr'进行比较是合法的
答案 4 :(得分:0)
if (m_callback)
,但是我从来都不喜欢暗示强制转换为bool而更喜欢使用运算符来评估bool。它有点冗长,但这有效:
if (static_cast<void (SomeOtherClass::*)()>(NULL)==m_callback)
m_object->DoNormalCallback();
} else {
(m_object->*m_callback)();
}
仍然不确定为什么NDK版本的GCC需要演员。