Valor de retorno de la colocación nuevo
Considere el siguiente código C++14:
#include <cassert>
#include <new>
#include <type_traits>
struct NonStandardLayout
{
// ...
};
int main()
{
using T = NonStandardLayout;
std::aligned_storage_t< sizeof(T), alignof(T) > storage;
T *const valid_ptr = new(static_cast<void *>(&storage)) T;
T *const maybe_ptr = reinterpret_cast<T *>(&storage);
assert(maybe_ptr == valid_ptr); // ???
valid_ptr->T::~T();
return 0;
}
¿Está garantizado por el estándar que la afirmación en el ejemplo nunca fallará, para cualquier tipo T?
Discusión
Buscando en el último estándar ( http://eel.is/c++draft / ), no puedo ver ninguna referencia a este escenario en particular, pero he encontrado los siguientes párrafos que posiblemente apuntan a la respuesta "sí".
¿Es correcto de mi parte pensar que
[expr.new/15]
y
[nuevo.eliminar.colocación/2]
junto establece que el valor de valid_ptr
será igual a la dirección de storage
, siempre?
Si es así, es cierto que el reinterpret_cast
producirá un puntero a un objeto construido? Porque,
[expr.reinterpretar.reparto / 7],
[expr.estática.reparto / 13]
y
[básica.compuesto/4]
juntos parecen indicar que debería ser el caso.
De mis observaciones, las implementaciones de bibliotecas del asignador predeterminado parecen ser similares a esto y sin preocupaciones! Es realmente seguro lanzar así?
Cómo ¿podemos estar seguros de que los dos indicadores serán los mismos, o podemos?
2 answers
Me sorprende que nadie haya mencionado este contraejemplo barato todavía:
struct foo {
static foo f;
// might seem dubious but doesn't violate anything
void* operator new(size_t, void* p) {return &f;}
};
Sin embargo, a menos que se llame a una versión de colocación específica de clase, su aserción debería mantenerse. Ambas expresiones tienen que representar la misma dirección como se explica en la otra respuesta (el punto principal es que el estándar non-allocating operator new
simplemente devuelve el argumento puntero y la nueva expresión no hace nada sofisticado), y ninguno de estos es un puntero pasado el final de algún objeto así, por [expr.eq] / 2, comparan igual.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-28 11:00:31
18.6.1.3 Formularios de colocación [nuevo.eliminar.colocación]
Void* operator new (std:: size_t size, void * ptr) noexcept;
Devuelve: ptr.
Se especifica inequívocamente que el operador placement new
devuelve cualquier puntero que se le pase. "Devuelve: ptr". No puedo ser más claro que eso.
Eso, más o menos, sella el trato para mí en cuanto a" el valor devuelto de la colocación nueva " va: la colocación new
no hace nada al puntero que coloca, y siempre devuelve el mismo puntero.
Todo lo demás en su pregunta se relaciona con cualquier otro cambio que pueda ocurrir como resultado de los otros casts; pero está preguntando específicamente sobre el valor devuelto de la colocación new
, así que entiendo que está aceptando que todas las demás conversiones son solo conversiones de tipo, y no tienen ningún efecto sobre el puntero real, y solo estaba preguntando sobre la colocación nueva but pero también sería posible pasar por los otros casts, y hacer una determinación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-30 20:47:01