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)?


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.