Неуказанное неявное создание объекта

9

Поскольку P0593 неявное создание объектов для низкоуровневой манипуляции с объектами было принято, объекты теперь можно создавать неявно в C ++ 20.

В частности, формулировка, предложенная предложением, позволяет определенным операциям (таким как std::malloc) автоматически создавать и запускать время жизни объектов определенных типов, так называемые типы неявного времени жизни , если введение таких объектов приведет к тому, что программа с иным неопределенным поведением будет иметь определенное поведение. Смотрите [intro.object] / 10 .

Теперь в проекте также указывается, что, если существует несколько наборов таких объектов, которые можно было бы создать неявно, чтобы придать программе определенное поведение, неизвестно, какой из этих наборов создан. (Соответствующее предложение, по-видимому, отсутствует в последней редакции предложения, к которой я мог получить доступ, R5, но содержится в проекте коммита.)

Есть ли на самом деле программа, для которой этот выбор неявно созданного набора объектов является наблюдаемым? Другими словами, существует ли программа с определенным, но неуказанным поведением с помощью этого нового правила, так что можно из вывода вывести, какие наборы типов неявных объектов (из нескольких возможных) были созданы?

Или это предложение просто предназначено для разъяснения выполнения программы на абстрактной машине (без заметного влияния)?

грецкий орех
источник
2
(OT) если неявно созданный объект является int, можем ли мы назвать его «неявным int»?
ММ
Кажется неясным, должен ли выбор элемента из неопределенного набора быть известен в точке malloc
ММ
@MM Я предполагал, что выбор набора рассматривался как абстрактный выбор как единый выбор для всего выполнения программы вне потока выполнения, но с созданием, происходящим непосредственно в рассматриваемой операции (то есть std::malloc), иначе вы получите проблемы с определением быть рекурсивным в зависимости от будущего.
грецкий орех
Я задал еще один вопрос на эту тему: stackoverflow.com/questions/60627249 . Конечно, на ум приходят еще несколько следствий, но один вопрос за раз ..
ММ
В предложении утверждается, что такое разграничение невозможно, что важно, поскольку нет никакого выбора для того, чтобы сделать выбор «правильно», только оптимизации, которых можно было бы избежать, что в противном случае было бы ( очень строго) обоснованным.
Дэвис Херринг

Ответы:

9

Давайте возьмем пример в стандарте и немного изменим его:

#include <cstdlib>
struct X { int a, b; };
X *make_x() {
  // The call to std::malloc implicitly creates an object of type X
  // and its subobjects a and b, and returns a pointer to that X object
  // (or an object that is pointer-interconvertible ([basic.compound]) with it),
  // in order to give the subsequent class member access operations
  // defined behavior.
  X *p = (X*)std::malloc(sizeof(struct X) * 2); // me: added the *2
  p->a = 1;
  p->b = 2;
  return p;
}

Ранее существовал только один набор допустимых объектов, которые могли бы быть неявно созданы в этом хранилище - это должен быть ровно один X. Но теперь у нас есть память для двух Xс, но только запись в один из них, и ничто в этой программе никогда не затрагивает остальные байты. Таким образом, существует множество различных наборов объектов, которые могут быть созданы неявным образом - возможно, два Xс, может быть Xи два int, а может быть Xи восемь charс ...

Неизвестно, какой набор создан, потому что, если бы были какие-либо фактические наблюдения, это уменьшило бы возможности только тех наборов, которые были действительны. Если бы мы сделали что-то подобное, p[1]->a = 3то вселенная возможностей рухнет до одной с двумя Xs.

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

Барри
источник
В любом случае, это только мое предположение.
Барри
Таким образом, я понимаю, что просто нет способа различить / наблюдать существование или несуществование объектов различных типов неявного времени жизни без неопределенного поведения. В этом случае мне кажется, что это единственное использование « неопределенного поведения » в стандарте, которое на самом деле не может привести к различным наблюдаемым результатам.
грецкий орех
1
Или что , если только доступы через glvalues типа [сорта] char, unsigned charили std::byte? Полагаю, там может существовать объект любого тривиально копируемого типа?
Ашеплер
2
Даже в исходном примере также возможно создать объект массива вместе с одним Xобъектом.
ТК