Как стандарт мог бы разрешить косвенное обращение через нулевой указатель? - PullRequest
1 голос
/ 16 августа 2011

РЕДАКТИРОВАТЬ: Это связано с активной проблемой 232 для C ++ Standard Core Language Active Issues

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

Рассмотрим следующий код:

struct a { int x; };
struct b { int y; };

struct c: a, b { };

b *f(c *pointer_to_c) { return pointer_to_c; }

f(...) должен проверить, является ли pointer_to_c значением NULL, и вернуть NULL, если это так.(Указатель NULL всегда является указателем NULL, независимо от того, как вы его разыгрываете.)

Теперь рассмотрим следующее:

b *f_ref(c &reference_to_c) { return &reference_to_c; }

Первый вопрос: f_refнужно проверить, является ли &reference_to_c NULL?Второй вопрос: если C ++ в конечном итоге определяет поведение косвенности через нулевой указатель, означает ли это, что f_ref должен проверять NULL?(Я полагаю, что ответ зависит от того, что разрешено стандартом, т. Е. Если он говорит, что «приведение NULL-ссылки к базовому классу не определено для множественного наследования», то ответ явно нет.)

Для одного последнегоголоволомки, теперь рассмотрим это:

const b *f_const_ref(const c &reference_to_c) { return &reference_to_c; }

Должен ли f_const_ref проверять &reference_to_c до NULL?Кстати, в VC ++ 2010 все три функции были оптимизированы до f, то есть все три функции проверяют входные данные по NULL.

, так что вы не можете передать нулевую ссылку в четко определенномПрограмма, означает ли это, что если стандарт C ++ в конечном итоге разрешает косвенное обращение через нулевой указатель, это не может привести к выражению или подвыражению, которое иначе связалось бы с нулевым указателем и создало бы нулевую ссылку?Другими словами, если стандарт допускает косвенное обращение через нулевой указатель, как они могут это разрешить?

Ответы [ 4 ]

6 голосов
/ 16 августа 2011

Неверная ссылка на указатель NULL (т. Е. Неопределенное поведение).

Таким образом, невозможно получить ссылку на NULL (в допустимом коде).

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

Первый вопрос: нужно ли f_ref проверять, имеет ли & reference_to_c значение NULL?

Нет.

Второй вопрос: если C ++ в конечном итоге определяет поведение косвенного обращения через нулевой указатель, значит ли это, что f_ref должен проверять на NULL?

Да.Его неопределенное поведение.Таким образом, любые дальнейшие предположения бесполезны.

Для последней загадки, f_const_ref должен проверить & reference_to_c в NULL?

Нет.

3 голосов
/ 16 августа 2011

Если ваша ссылка в f_ref или f_const_ref равна NULL, вы находитесь в сфере неопределенного поведения.

Это не определено, потому что единственный способ получить NULL-ссылку - это разыменовать NULL-указатель. Таким образом, ниже не определено, хотя на g ++ 4.5.2 он будет выводить 0.

#include <iostream>
struct C {};
C* foo(C& r) {  return &r; }
int main() {
  C* c = NULL;

  std::cout << foo(*c) << std::endl;
  return 0;
}
2 голосов
/ 16 августа 2011

C ++ не позволяет это. Ссылка на NULL является недопустимой, и по стандартам это приведет к неопределенному поведению.

Сказав это, я никогда не видел, чтобы компилятор делал что-то кроме ваших ожиданий.

1 голос
/ 16 августа 2011

&reference_to_c никогда не может быть NULL.В параметре функции ссылка должна быть инициализирована с некоторым допустимым объектом.Так что &reference_to_c не может быть NULL.

...