我使用gcc8编译此代码:
#include <iostream>
class person
{
public:
virtual void setage()=0;
};
void test(person &object)
{
if (&object == NULL) {
std::cout << "NULL object1" << std::endl;
}
if (!(&object))
{
std::cout << "NULL object1" << std::endl;
}
}
int main()
{
person *object=NULL;
person &object1=*object;
test(object1);
}
然后,在编译和运行后会出现两个警告:
$ g ++ -std = c ++ 14 -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread -pedantic-errors main.cpp -lm -latomic -lstdc ++ fs && ./a.out
main.cpp:在函数'void test(person&)'中:
main.cpp:11:17:警告:编译器可以假定 “对象”永远不会为NULL [-Waddress]
if (&object == NULL) { ^
main.cpp:15:18:警告:编译器可以假定 “对象”永远不会为NULL [-Waddress]
if (!(&object)) ^
main.cpp:15:5:警告:与参数NULL比较的非null参数'object' [-Wnonnull-compare]
if (!(&object)) ^~
main.cpp:11:5:警告:与参数NULL相比,非null参数'object' [-Wnonnull-compare]
if (&object == NULL) { ^~
object
中test
的地址即使传递了NULL引用值也不为NULL?object
中的引用test
永远不能为NULL,因此我们可以删除代码if (&object == NULL){...}
和if (&object == NULL) {...}
来避免这两个警告,对吗? 感谢提示。
答案 0 :(得分:9)
在格式正确的C ++程序中,引用永远不能为null。初始化引用的唯一有效方法是将其绑定到有效对象。可能发生“空引用”的唯一方法是,如果像您一样取消引用空指针。但是,即使在您检查&object == NULL
之前,程序的行为也是不确定的。该错误位于传递“空引用”的代码中,并且必须在那里修复。
因此,编译器警告您添加了多余的检查,可保护您从无到有,因为需要修复的损坏代码不在您的函数之内。
答案 1 :(得分:3)
Person* ptr_object = NULL;
Person& ref_object= *ptr_object;
通过在此处取消引用ptr_object,可以取消引用NULL指针,这是未定义的行为。引用不应引用NULL。