auto a = new int[0];
De acuerdo con [basic.compound.3] , el valor almacenado a
debe ser uno de los siguientes:
- Un puntero a un objeto (de tipo
int
)
- Un puntero más allá del final de un objeto.
- Nulo
- Inválido
Podemos descartar la primera posibilidad ya que no se int
construyeron objetos de tipo . Se descarta la tercera posibilidad ya que C ++ requiere que se devuelva un puntero no nulo (consulte [basic.stc.dynamic.allocation.2] ). Por lo tanto, nos quedan dos posibilidades: un puntero más allá del final de un objeto o un puntero no válido.
Me inclinaría a ver a
como un puntero pasado-fin, pero no tengo una referencia acreditada para establecer definitivamente eso. (Sin embargo, hay una fuerte implicación de esto en [basic.stc] , ver cómo puedes usardelete
este puntero). Así que consideraré ambas posibilidades en esta respuesta.
Entre la inicialización y la eliminación de la copia, ¿puede leer el puntero en a + 1
?
El comportamiento es indefinido, según lo dictado por [expr.add.4] , independientemente de la posibilidad que se aplique desde arriba.
Si se a
trata de un puntero pasado, se considera que apunta al elemento hipotético en el índice 0
de una matriz sin elementos. Agregar el entero j
a a
se define solo cuando 0≤0+j≤n
, donde n
es el tamaño de la matriz. En nuestro caso, n
es cero, por lo que la suma a+j
se define solo cuando j
es 0
. En particular, la suma 1
no está definida.
Si a
no es válido, entonces caemos claramente en "De lo contrario, el comportamiento no está definido". (No es sorprendente que los casos definidos solo cubran valores de puntero válidos).
Por otra parte, el lenguaje no permite que el compilador conjunto a
de nullptr
?
No. De la mencionada [basic.stc.dynamic.allocation.2] : "Si la solicitud tiene éxito, el valor devuelto por una función de asignación reemplazable es un valor de puntero no nulo" . También hay una nota al pie que dice que C ++ (pero no C) requiere un puntero no nulo en respuesta a una solicitud cero.
a
con seguridad (ciertamente no puedes desreferenciarlo).