Нулевые ссылки в С++

Началось с того, что мне предложили взглянуть некий на “интересный” код. Там было что-то вроде:

...
class A { virtual void f() {} };
class B {};

int main() {
  A a;
  try {
    B& b = dynamic_cast<B&>(a);
    if (&b == 0) {
      // ...
    }
  } catch (...) {
    std::cout << "Got it!" << std::endl;
  }
  return 0;
}

Я слегка выпал в осадок от уведенного, а в частности, от строки if (&b == 0) {. До сего времени я пребывал в осознании факта, что ссылка в С++ либо существует и указывает на реальный объект, либо ее нет вообще. И если тут приведение типа к B& не срабатывает, то будет исключение, и управление все равно улетит в другое место, и проверять как-либо b бессмысленно.

Но тут мне объяснили, что в данном конкретном случае код может компилироваться, когда у компилятора выключена поддержка исключений. И эта проверка как раз защита от этого.

Ну да ладно. Оставим это на откуп странным компиляторам на AIX и SUN, и людям, использующим исключения, но почему-то компилирующие с принудительным их выключением в компиляторе.

Меня заинтересовал другой вопрос: как вообще ссылка может существовать отдельно от объекта. Оказывается, может:

int& a = *(int*)0;
int main() { a = 123; }

Данный код прекрасно компилируется Студией (2010) и компилятором SUN (этот хоть предупреждение выдает), и также прекрасно падается при запуске по понятой причине.

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


Оригинальный пост | Disclaimer

Комментарии