Подтвердить что ты не робот

Назначение ссылки путем разыменования указателя NULL

int&  fun()
{
    int * temp = NULL;
    return *temp;
}

В вышеописанном методе я пытаюсь выполнить разыменование указателя NULL. Когда я вызываю эту функцию, она не дает исключения. Я нашел, когда тип возврата по ссылке не дает исключение, если он по значению, то он делает. Даже если разыменование указателя NULL используется для ссылки (например, ниже строки), то и это не дает.

int* temp = NULL:
int& temp1 = *temp;

Здесь мой вопрос в том, что компилятор не выполняет разыменование в случае ссылки?

4b9b3361

Ответ 1

Разыменование нулевого указателя Undefined Поведение.

An Undefined Поведение означает, что все может случиться, поэтому определить поведение для этого невозможно.

По общему признанию, я собираюсь добавить эту стандартную цитату С++ в n-й раз, но, похоже, она должна быть.

Что касается поведения Undefined,

Стандартная секция С++ 1.3.24:

Допустимое поведение Undefined варьируется от полного игнорирования ситуации с непредсказуемыми результатами, ведения во время перевода или выполнения программы документированным образом, характерным для среды (с выдачей диагностического сообщения или без него), до прекращения перевода или выполнение (с выдачей диагностического сообщения).

Примечание:
Кроме того, просто довести его до вашего сведения:
Использование возвращенной ссылки или указателя на локальную переменную внутри функции также является Undefined Поведение. Вы должны назначить указатель на freestore (heap) с помощью new, а затем вернуть ссылку/указатель на него.

EDIT:
Как @James Макнеллис, соответственно указывает в комментариях,
Если возвращенный указатель или ссылка не используется, поведение четко определено.

Ответ 2

Когда вы разыскиваете нулевой указатель, вы не обязательно получаете исключение; все, что гарантировано, заключается в том, что поведение undefined (что на самом деле означает, что нет никакой гарантии относительно того, что такое поведение).

После вычисления выражения *temp невозможно определить поведение программы.

Ответ 3

Вам не разрешено разыменовывать нулевой указатель, поэтому компилятор может генерировать код, предполагая, что вы этого не делаете. Если вы это сделаете, компилятор может быть приятным и сказать вам, но это не обязательно. Это ваша часть контракта, в которой говорится, что вы не должны этого делать.

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

Ответ 4

Не * нулевой указатель, это UB. (undefined поведение, вы никогда не можете предположить, что он сделает что-нибудь, кроме освещения вашей собаки в огне и заставляя вас забирать шубы, которые приведут к ФАБУЛЬНЫМ анекдотам)

Некоторая история и информация о нулевых указателях в семействе Algol/C: http://en.wikipedia.org/wiki/Pointer_(computing)#Null_pointer

Примеры и последствия поведения undefined: http://en.wikipedia.org/wiki/Undefined_behavior#Examples_in_C

Ответ 5

Я не уверен, что понимаю, что вы пытаетесь сделать. Выделение указателя ** NULL ** не определено.

Если вы хотите указать, что метод не всегда возвращает значение, вы можете объявить его как:

bool fun (int & val);

или stl way (аналогично std:: map insert):

std::pair<int, bool> fun();

или ускорить путь:

boost::optional<int> fun();