Ссылка не может быть NULL или может быть NULL? - PullRequest
9 голосов
/ 29 января 2010

Я прочитал из Википедии, что:

«Ссылки не могут быть нулевыми, тогда как указатели могут;каждая ссылка относится к какому-либо объекту, хотя она может или не может быть действительной. ”

Но я не верю, что из-за следующего кода, посмотрите на него, компилятор не выдает ошибку:

class person
{
  public:
    virtual void setage()=0;
};

int main()
{
  person *object=NULL;
  person &object1=*object;
}

Пожалуйста, уточните этот пункт.

Ответы [ 7 ]

20 голосов
/ 29 января 2010

В вашем коде:

person *object=NULL;
person &object1=*object;

вы разыменовываете нулевой указатель, так что вы получаете неопределенное поведение. И чтобы ответить на ваш вопрос, нет такой вещи, как NULL ссылка.

И чтобы ответить на другую часть вашего вопроса, просто потому, что программа компилируется, нет никакой гарантии, что она правильная или будет работать. Компиляторы C ++ не обязаны даже пытаться диагностировать тип ошибок, содержащихся в вашем коде.

9 голосов
/ 29 января 2010

Сказать person &object1=*object - это не то же самое, что сказать person &object1=NULL. Возможно, компилятор не настолько умен, чтобы обнаружить, что вы разыменовываете нулевой указатель, но в любом случае вы получите ошибку времени выполнения. Так что они все еще правдивы;)

4 голосов
/ 30 января 2010

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

3 голосов
/ 29 января 2010

это приведет к краху вашей программы. Вы пытались запустить его? выполнение объекта * будет содержать нулевой указатель, поэтому фактически ваша ссылка никогда не будет назначена.

2 голосов
/ 29 января 2010

Ну, вы можете делать все, что вы хотите в C ++. Другой пример:

person &object1 = *( reinterpret_cast<person*>(0) );

Вы вызываете неопределенное поведение в приведенном выше случае, кроме упомянутого вами случая!

1 голос
/ 20 декабря 2014

clang 3.5 даже предупреждает о возможной последующей нулевой проверке ссылки:

/tmp/person.C:11:6: warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to
      always convert to true [-Wundefined-bool-conversion]
if (&object1) {}
~~   ^~~~~~~
1 warning generated.
0 голосов
/ 17 июня 2019

gcc8 выдаст предупреждение об этом:

предупреждение: компилятор может предположить, что адрес 'object1' никогда не будет NULL [-Waddress]

Небольшая демонстрация:

#include <iostream>

class person
{
    public:
        virtual void setage()=0;
};

int main()
{
    person *object=NULL;
    person &object1=*object;

    if (&object1 == NULL) {
        std::cout << "NULL object1" << std::endl;
    }

    if (!(&object1)) {
        std::cout << "NULL object1 " << std::endl;
    }
}

Скомпилируйте и запустите вывод:

g ++ -std = c ++ 2a -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread -pedantic-errors main.cpp -lm -latomic -lstdc ++ fs && ./a.out

main.cpp: в функции 'int main ()':

main.cpp: 14: 18: предупреждение: компилятор может предположить, что адрес 'object1' никогда не будет NULL [-Waddress]

 if (&object1 == NULL) {

              ^

main.cpp: 18: 19: предупреждение: компилятор может предположить, что адрес 'object1' никогда не будет NULL [-Waddress]

 if (!(&object1)) {

               ^

NULL object1

NULL object1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...