Как исправить предупреждение «компилятор может предположить, что адрес объекта никогда не будет равен NULL» - PullRequest
0 голосов
/ 17 июня 2019

Я использую 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 [-Wnonnull-сравнение]

 if (!(&object))

 ^~

main.cpp: 11: 5: предупреждение: ненулевой аргумент 'объект' по сравнению с NULL [-Wnonnull-сравнение]

 if (&object == NULL) {

 ^~
  1. Почему адрес object в функции test не равен NULL, даже если ему передается значение ссылки NULL?
  2. Кажется, что ссылка object в функцииtest никогда не может быть NULL, поэтомумы можем просто удалить код if (&object == NULL){...} и if (&object == NULL) {...}, чтобы избежать этих двух предупреждений, верно?

Спасибо за подсказки.

Ответы [ 2 ]

9 голосов
/ 17 июня 2019

Ссылки никогда не бывают нулевыми в правильно сформированной программе C ++.Единственный допустимый способ инициализации ссылки - это привязка ее к действительному объекту.Единственный способ, которым может произойти «нулевая ссылка» - это разыменовать нулевой указатель, как у вас.Но тогда поведение вашей программы не определено даже до того, как вы проверите &object == NULL.Ошибка в коде, который передает «нулевую ссылку», и она должна быть там исправлена.

Поэтому компилятор предупреждает вас, что вы добавили лишнюю проверку, которая защищает вас отпрактически ничего, потому что сломанный код, который нужно исправить, находится за пределами вашей функции.

3 голосов
/ 17 июня 2019
Person* ptr_object = NULL;
Person& ref_object= *ptr_object;

Разыменовывая ptr_object, вы освобождаете указатель NULL, что является неопределенным поведением.Ссылка не должна ссылаться на NULL.

...