Почему небезопасное приведение с использованием оператора static_cast не приводит к сбою?

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

#include <iostream>

using namespace std;

class base
{

   public:
       void func()
      {
         cout << "base::func()" << endl;
      }

};

class derived : public base
{
   public:
       void func()
      {
         cout << "derived::func()" << endl;
      }

};

void dummy(base *bptr)
{
  derived *dptr = static_cast<derived*> (bptr);
  dptr->func();
}

int main()
{
   base bob1;
   derived dob1;

   dummy(&dob1); //Line1
   dummy(&bob1); //Line2
}

В Line1 я передаю адрес объекта производного класса функции dummy, которая принимает указатель на объект базового класса. Таким образом, static_cast в функции dummy безопасна.

В Line2 я передаю адрес объекта базового класса в функцию. Так что static_cast в функции dummy небезопасно.

Но когда я выполняю код, программа ведет себя нормально. Я думал, по слову not safe программа должна крашиться во время выполнения. Но никакого сбоя не произошло.

Вот результат, который я получаю.

derived::func()
derived::func()

По какой причине программа не падает во время выполнения?


person nitin_cherian    schedule 18.07.2012    source источник
comment
Плохой код гораздо труднее понять, чем хороший.   -  person David Schwartz    schedule 18.07.2012
comment
@ Дэвид: Не могли бы вы уточнить?   -  person nitin_cherian    schedule 18.07.2012
comment
возможный дубликат stackoverflow.com/questions/2469013/   -  person celavek    schedule 18.07.2012
comment
@LinuxPenseur: понимание плохого кода требует очень глубокого понимания решений по реализации, принимаемых компилятором. Хороший код тщательно сконструирован таким образом, чтобы его поведение не зависело от этих решений.   -  person David Schwartz    schedule 18.07.2012


Ответы (2)


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

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

person Luchian Grigore    schedule 18.07.2012

Одной из основных концепций C++ является неопределенное поведение. Когда вы выполняете операцию, которая приводит к неопределенному поведению, например. статического приведения указателя, который не указывает на объект приведенного типа, поведение вашей программы буквально неопределенно: стандарт не определяет какое-либо конкретное поведение. Платформа не обязана делать что-то конкретное, любое поведение, которое она показывает, допустимо в соответствии со стандартом.

Это неопределенное поведение включает в себя молчаливые действия, которые выглядят для вас нормальным поведением. Нет никакой гарантии для ошибки сегментации или любой другой диагностики.

person thiton    schedule 18.07.2012