Объяснение выходных данных при вызове функций с использованием указателей wild и null - PullRequest
0 голосов
/ 22 февраля 2020

Недавно меня попросили предсказать вывод следующей программы в интервью:

#include <bits/stdc++.h>
using namespace std;

class a {
 public:
  int x = 10;
  void f() { cout << "hello" << endl; }

  void g() { cout << x << endl; }
};

int main() {
  a* ptr = new a();
  a* ptr1;
  a* ptr2 = NULL;
  ptr->f();
  ptr1->f();
  ptr2->f();

  ptr->g();
  ptr1->g();
  ptr2->g();
}

Когда функция f () вызывается с использованием нулевых и подстановочных указателей, вывод выводится как привет, но когда функция g () вызывается с использованием этих двух указателей, на консоли не выводится никакой информации. В чем может быть причина такого поведения?

Ответы [ 3 ]

3 голосов
/ 22 февраля 2020

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

Кроме того, , пожалуйста, , прочитайте Почему я не должен #include <bits/stdc++.h>?

1 голос
/ 22 февраля 2020

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

0 голосов
/ 22 февраля 2020

Ваша программа имеет неопределенное поведение. Сказав это, есть правдоподобное объяснение того, почему вызовы f, кажется, работают, в то время как вызовы g вызывают странное поведение.

Функции много раз концептуально переводятся как:

void mangled_function_for_f(a* const this)
{
   cout << "hello" << endl;
}

void mangled_function_for_g(a* const this)
{
   cout << this->x << endl;
}

Обратите внимание, что this не используется в f. Следовательно, звонки на f кажутся нормальными. Не так с g.

PS Не рассчитывайте на мое объяснение на каждой платформе или даже на одной и той же платформе с разными опциями компилятора. Лучше всего избегать кода, который вызывает неопределенное поведение.

...