如何解决警告“编译器可以假设'object'的地址永远不会为NULL”

时间:2019-06-17 08:56:18

标签: c++ gcc-warning

我使用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) {

 ^~
  1. 为什么函数objecttest的地址即使传递了NULL引用值也不为NULL?
  2. 似乎函数object中的引用test永远不能为NULL,因此我们可以删除代码if (&object == NULL){...}if (&object == NULL) {...}来避免这两个警告,对吗?

感谢提示。

2 个答案:

答案 0 :(得分:9)

在格式正确的C ++程序中,引用永远不能为null。初始化引用的唯一有效方法是将其绑定到有效对象。可能发生“空引用”的唯一方法是,如果像您一样取消引用空指针。但是,即使在您检查&object == NULL之前,程序的行为也是不确定的。该错误位于传递“空引用”的代码中,并且必须在那里修复。

因此,编译器警告您添加了多余的检查,可保护您从无到有,因为需要修复的损坏代码不在您的函数之内。

答案 1 :(得分:3)

Person* ptr_object = NULL;
Person& ref_object= *ptr_object;

通过在此处取消引用ptr_object,可以取消引用NULL指针,这是未定义的行为。引用不应引用NULL。