Nieokreślone niejawne tworzenie obiektu

9

Ponieważ P0593 Domniemane tworzenie obiektów do manipulacji obiektami na niskim poziomie zostało zaakceptowane, obiekty mogą być teraz tworzone niejawnie w C ++ 20.

W szczególności sformułowanie wprowadzone we wniosku pozwala niektórym operacjom (np. std::malloc) Automatycznie tworzyć i uruchamiać okres istnienia obiektów określonych typów, tak zwanych typów niejawnych , jeśli wprowadzenie takich obiektów spowodowałoby, że program o innym niezdefiniowanym zachowaniu miałby określone zachowanie. Zobacz [przedmiot wstępny] / 10 .

W wersji roboczej stwierdza się teraz, że jeśli istnieje wiele zestawów takich obiektów, które mogłyby zostać utworzone pośrednio w celu nadania programowi określonego zachowania, nie jest określone, który z tych zestawów zostanie utworzony. (Wydaje się, że odpowiednie zdanie nie występuje w ostatniej poprawce wniosku, do której mogłem uzyskać dostęp, R5, ale jest w projekcie zatwierdzenia.)

Czy istnieje program, dla którego można zaobserwować ten wybór niejawnie utworzonego zestawu obiektów? Innymi słowy, czy istnieje program o zdefiniowanym, ale nieokreślonym zachowaniu dzięki tej nowej regule, tak że można na podstawie danych wyjściowych wywnioskować, które zestawy typów niejawnych obiektów (z więcej niż jednego możliwego) zostały utworzone?

A może to zdanie miało jedynie na celu wyjaśnienie wykonania programu na abstrakcyjnej maszynie (bez zauważalnego wpływu)?

orzech włoski
źródło
2
(OT) jeśli niejawnie utworzony obiekt jest intem, czy możemy go nazwać „niejawnym int”?
MM
Wydaje się niejasne, czy wybór elementu z nieokreślonego zestawu musi być znany w punkcie malloc
MM
@MM Zakładałem, że wybór zestawu został uznany za abstrakcyjny jako pojedynczy wybór dla wykonania całego programu poza przepływem wykonania, ale z tworzeniem odbywa się bezpośrednio w danej operacji (tj. std::malloc), W przeciwnym razie występują problemy z definicją rekurencyjnie w zależności od przyszłości.
orzech
Zadałem kolejne pytanie na ten temat, stackoverflow.com/questions/60627249 . Oczywiście przychodzą mi na myśl kolejne konsekwencje, ale jedno pytanie na raz ...
MM
Propozycja twierdzi, że nie można tak rozróżnić, co jest ważne, ponieważ nie ma możliwości, aby wybór został dokonany „poprawnie”, jedynie optymalizacje, których można by uniknąć, które w przeciwnym razie byłyby ( bardzo ściśle) ważne.
Davis Herring

Odpowiedzi:

9

Weźmy przykład ze standardu i zmieńmy go trochę:

#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;
}

Wcześniej istniał tylko jeden zestaw prawidłowych obiektów, które można było utworzyć pośrednio w tym magazynie - musiał to być dokładnie jeden X. Ale teraz mamy pamięć dla dwóch Xsekund, ale piszemy tylko do jednego z nich i nic w tym programie nigdy nie dotyka reszty bajtów. Istnieje więc wiele różnych zestawów obiektów, które można niejawnie utworzyć - może dwa Xs, może Xi dwa int, może Xi osiemchar , ...

Nie można zaobserwować, który zestaw jest tworzony, ponieważ gdyby były jakieś rzeczywiste obserwacje, ograniczyłoby to możliwości tylko do tych zbiorów, które były ważne. Gdybyśmy coś takiego zrobili, p[1]->a = 3wówczas wszechświat możliwości zawaliłby się do jednego z dwomaX s.

Innymi słowy, wiele zestawów niejawnie utworzonych obiektów jest prawdopodobnie tylko wtedy, gdy w programie nie ma wystarczającej liczby obserwacji, aby odróżnić ich ważność. Gdyby istniał sposób na rozróżnienie, to z definicji nie wszystkie byłyby ważne.

Barry
źródło
W każdym razie to tylko moje przypuszczenie.
Barry
Przyjmuję więc, że po prostu nie ma sposobu, aby odróżnić / zaobserwować istnienie lub nieistnienie przedmiotów różnych typów życia niejawnego bez nieokreślonego zachowania. W takim przypadku wydaje mi się, że jest to jedyne użycie „ nieokreślonego zachowania ” w standardzie, które nie może faktycznie prowadzić do różnych obserwowalnych wyników.
orzech
1
Albo co jeśli tylko dostępy są poprzez glvalues typu [cv] char, unsigned charlub std::byte? Wydaje mi się, że może istnieć także obiekt dowolnego typu, który można skopiować.
aschepler
2
Nawet w oryginalnym przykładzie możliwe jest również utworzenie obiektu tablicowego razem z jednym Xobiektem.
TC