¿Qué sucederá cuando llame a una función miembro en un puntero de objeto NULL?

Me dieron lo siguiente como una pregunta de entrevista:

class A { public: void fun() { std::cout << "fun" <fun(); 

¿Qué sucederá cuando se ejecute este código y por qué?


Ver también:

  • ¿Cuándo la invocación de una función miembro en una instancia nula da como resultado un comportamiento indefinido?

Es un comportamiento indefinido, por lo que cualquier cosa puede pasar.

Un posible resultado sería que simplemente imprime "fun" ya que el método no accede a las variables miembro del objeto al que se llama (no es necesario acceder a la memoria donde supuestamente vive el objeto, por lo que las violaciones de acceso no se realizan). necesariamente ocurre).

Según el estándar, esto es un comportamiento indefinido y, por lo tanto, algo muy malo. En realidad, la mayoría de las plataformas de progtwigción (tanto para X86 como para otras architectures) funcionarán bien.

¿Por qué? Considere cómo se implementan las funciones de clase en C ++. Esta no es una función virtual, por lo tanto, esto puede ser una llamada estática a una dirección conocida. En el ensamblaje x86, podemos ver esto como

 mov A, 0 mov ecx, A call a__fun 

ya que a__fun no requiere datos de instancia, aunque reciba un null este puntero, no pasará nada.

Todavía el código de mierda y cualquier comstackdor gritarán, pero se puede ejecutar.

El comportamiento más probable, en la mayoría de las computadoras modernas, es que se ejecutará e imprimirá “diversión” porque:

  • C ++ no comprueba si el puntero es NULL antes de llamar a la función
  • fun() no es virtual, por lo que no es necesario hacer referencia a un vtable para llamar a fun()
  • fun() nunca accede a ninguna variable miembro en A por lo que no necesita desreferenciar el nulo de this puntero.

No podemos saber lo que será . Todo puede suceder, porque el progtwig expone el comportamiento indefinido. Consulte ¿La invocación de una función miembro en una instancia nula causa un comportamiento indefinido? .

Lo he intentado varias veces, todo el tiempo la salida se vuelve “divertida”, esto es porque la fun función es independiente de la instancia a . mientras llamas a->fun(); a puntos a 0 por lo que este es un comportamiento indefinido, pero en la mayoría de los comstackdores no debería producirse un locking.

Tres puntos pueden ayudar:

1) Todas las funciones se almacenan en el código o la sección de texto.

2) Las funciones no virtuales se resuelven al momento de cumplir.

3) Al llamar a las funciones miembro de la clase, pasamos el objeto actual como this puntero a esa función.

Al llegar a su pregunta, aquí la función de fun() ya está en la memoria (sección de código / sección de texto). Como función fun() no es virtual, se resolverá en el momento de cumplimiento (es decir, para esta línea saltará a la instrucción X en la sección de código con this puntero como NULL ). Como no se usa / llama ninguna función miembro ni función virtual en la función fun() , funciona bien.