Что значит получить хранилище? - PullRequest
4 голосов
/ 12 октября 2019

[basic.indet] p1 говорит:

Когда получено хранилище для объекта с автоматическим или динамическим сроком хранения, объект имеет неопределенное значение, а если нетинициализация выполняется для объекта, этот объект сохраняет неопределенное значение до тех пор, пока это значение не будет заменено.

Что конкретно означает, что для объекта будет получено хранилище? Рассмотрим следующий фрагмент кода:

int a = 0;
new (&a) int;

Когда будет получено хранилище для объекта int, созданного с помощью new-expression ? Это происходит, когда было получено хранилище для исходного объекта, созданного по определению, или оно будет получено при создании объекта с помощью new-expression ?

(Примечание: согласно P0593 этот новый объект будет иметь неопределенное значение из-за [basic.life] p4 , однако это явно не указано, если только хранение не считается полученным, когда второй объектсоздан)

Редактировать: Кажется, что это является предметом отчета о дефектах без ответа CWG 1997

Ответы [ 2 ]

1 голос
/ 12 октября 2019

На самом деле, это довольно просто . From [expr.new] / 8:

Новое выражение может получить хранилище для объекта, вызвав функцию выделения

Placement-новая функция распределения. Он может возвращать только тот же указатель, который был ему дан, но этот процесс все еще считается «получением хранилища для объекта». Это хранилище является хранилищем, на которое указывает &a. И, следовательно, он работает именно так, как ожидалось. Хранилище, используемое в данный момент a, используется повторно. Таким образом, текущий a заканчивает свое время жизни, а новый int начинает свое время жизни в том же хранилище.

«Получить хранилище для объекта» не означает «создать хранилище, которого там не было»до". Это означает именно то, что написано: получить часть хранилища с целью помещения туда объекта. Это отличается от простого получения части хранилища. То, что часть памяти уже может использоваться другим объектом, является ортогональным.

1 голос
/ 12 октября 2019

Хранилище изначально , выделить d для автоматического объекта. Новое место размещения затем повторно использует s, это хранилище для динамического объекта.

Стандарт, как представляется, не определяет значение слова «получить» в отношении выделения и повторного использования. Если бы он ограничивался тем же, что и «выделить», то это был бы избыточный термин, поэтому разумно предположить, что он охватывает как распределение, так и повторное использование.

При такой интерпретации хранилище будет иметьбыли получены при размещении нового выражения. И действительно, значение будет неопределенным. Есть способ сохранить значение:

int a = 0;
int orig = a;
new (&a) int(orig);

Достойный оптимизирующий компилятор может видеть, что копии являются избыточными. Для массивов то же самое может быть достигнуто с помощью memcpy, и они могут быть оптимизированы слишком долго, пока длина постоянна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...