Ahora que una variable se puede definir en cualquier parte del bloque, podría parecer que el espacio para una variable no se reserva hasta el momento en que se define. En realidad, lo más probable es que el compilador siga la práctica de C de reservar todo el espacio para el bloque en la llave de apertura del bloque. No importa porque, como programador, no puede acceder al espacio asociado (es decir, el objeto) hasta que ha sido definido[61]. Aunque el espacio se pida al comienzo del bloque, la llamada al constructor no ocurre hasta el punto en el que se define el objeto ya que el identificador no está disponible hasta entonces. El compilador incluso comprueba que no ponga la definición del objeto (y por tanto la llamada al constructor) en un punto que dependa de una sentencia condicional, como en una sentencia switch o algún lugar que pueda saltar un goto. Descomentar las sentencias del siguiente código generará un error o aviso:
//: C06:Nojump.cpp // Can't jump past constructors class X { public: X(); }; X::X() {} void f(int i) { if(i < 10) { //! goto jump1; // Error: goto bypasses init } X x1; // Constructor called here jump1: switch(i) { case 1 : X x2; // Constructor called here break; //! case 2 : // Error: case bypasses init X x3; // Constructor called here break; } } int main() { f(9); f(11); }///:~
Listado 6.3. C06/Nojump.cpp
En el código anterior, tanto el goto como el switch pueden saltar la sentencia en la que se invoca un constructor. Ese objeto estaría en el ámbito incluso si no se ha invocado el constructor, de modo que el compilador dará un mensaje de error. Esto garantiza de nuevo que un objeto no se puede crear si no se inicializa.
Todo el espacio de almacenamiento necesario se asigna en la pila, por supuesto. Ese espacio lo reserva el compilador moviendo el puntero de pila «hacia abajo» (dependiendo de la máquina implica incrementar o decrementar el valor del puntero de pila). Los objetos también se pueden alojar en el montículo usando new, algo que se verá en el Capítulo 13.
[61] De acuerdo, probablemente podría trucarlo usando punteros, pero estaría portándose muy, muy mal.