С правилом «как если» компилятору разрешено выполнять любую оптимизацию, если наблюдаемое поведение идентично.
Немедленное освобождение q
/ p
не будет разрешено, поскольку тогда вы будете использовать висячий указатель.
Хотя он может вызывать деструктор до конца области действия:
{
int* p = new int(0);
std::unique_ptr<int> q(p);
...
// make use of 'p'
...
// No longer use of p (and q)
...
// Ok, can delete p/q now (as long there are no observable behaviors changes)
...
}
Поскольку operator new
/ delete
может быть изменен глобально, компилятору обычно не хватает информации (компоновщик хотя), поэтому рассмотрим их (потенциально) наблюдаемое поведение (как и любые внешние функции).
c ++ 14 допускает некоторые варианты / оптимизацию нового выражения, поэтому
{
delete new int(42);
int* p1 = new int(0);
int* p2 = new int(0);
std::unique_ptr<int> q2(p2);
std::unique_ptr<int> q1(p1);
...
// make use of 'p1'/p2
...
}
Может быть "заменённым" на
{
// delete new int(42); // optimized out
std::unique_ptr<int[]> qs{new int [] {0, 0}}; // only one allocation instead of 2
int* p1 = q->get();
int* p2 = q->get() + 1;
...
// make use of 'p1'/p2
...
}