Penciptaan Obyek Tersirat yang Tidak Ditentukan

9

Karena P0593 penciptaan objek secara implisit untuk manipulasi objek tingkat rendah telah diterima, objek sekarang dapat dibuat secara implisit dalam C ++ 20.

Khususnya kata-kata yang diperkenalkan oleh proposal memungkinkan operasi tertentu (seperti std::malloc) untuk secara otomatis membuat dan memulai masa objek dari tipe tertentu, yang disebut tipe implisit-seumur hidup , jika pengenalan objek tersebut akan menyebabkan program dengan perilaku yang tidak ditentukan untuk memiliki perilaku yang didefinisikan. Lihat [intro.object] / 10 .

Draf sekarang lebih lanjut menyatakan bahwa jika ada beberapa set objek seperti itu yang dapat dibuat secara implisit untuk memberikan perilaku yang ditentukan program, itu tidak ditentukan yang mana dari set ini dibuat. (Kalimat yang relevan tampaknya tidak hadir dalam revisi proposal terakhir yang dapat saya akses, R5, tetapi dalam konsep komit.)

Apakah benar-benar ada program yang dapat diamati pilihan set objek yang dibuat secara implisit ini? Dengan kata lain, apakah ada program dengan perilaku yang ditentukan, tetapi tidak ditentukan, melalui aturan baru ini, sehingga dimungkinkan untuk menyimpulkan dari output yang menetapkan jenis objek implisit (dari lebih dari satu yang mungkin) dibuat?

Atau apakah kalimat ini hanya dimaksudkan untuk memperjelas pelaksanaan program pada mesin abstrak (tanpa dampak yang dapat diamati)?

kenari
sumber
2
(OT) jika objek yang dibuat secara implisit adalah sebuah int, dapatkah kita menyebutnya "implisit int"?
MM
Tampaknya tidak jelas apakah pilihan elemen dari set yang tidak ditentukan harus diketahui pada titik malloc
MM
@ MM Saya berasumsi bahwa pilihan set dianggap terjadi secara abstrak sebagai pilihan tunggal untuk seluruh eksekusi program di luar aliran eksekusi, tetapi dengan penciptaan terjadi langsung pada operasi yang dimaksud (yaitu std::malloc), jika tidak, Anda mendapatkan masalah dengan definisi secara rekursif tergantung pada masa depan.
walnut
Saya membuat pertanyaan lain tentang topik itu, stackoverflow.com/questions/60627249 . Tentu saja beberapa konsekuensi wajar muncul dalam pikiran tetapi satu pertanyaan pada suatu waktu ..
MM
Proposal mengklaim bahwa tidak mungkin untuk dibedakan, yang penting karena tidak ada cara untuk pilihan yang dibuat "dengan benar", hanya optimasi untuk menghindari yang seharusnya ( sangat ketat) valid.
Davis Herring

Jawaban:

9

Mari kita ambil contoh dalam standar dan mengubahnya sedikit:

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

Sebelumnya, hanya ada satu set objek yang valid yang dapat dibuat secara implisit dalam penyimpanan itu - itu harus tepat satu X. Tapi sekarang, kami memiliki penyimpanan untuk dua Xs, tetapi hanya menulis ke salah satu dari mereka, dan tidak ada dalam program ini yang pernah menyentuh sisa byte. Jadi ada banyak set objek yang berbeda yang dapat dibuat secara implisit - mungkin dua Xs, mungkin an Xdan dua ints, mungkin an Xdan delapan chars, ...

Tidak dapat diamati set mana yang dibuat, karena jika ada pengamatan yang sebenarnya, itu akan mengurangi kemungkinan hanya set yang valid. Jika kita melakukan sesuatu seperti p[1]->a = 3itu, maka alam semesta dari kemungkinan runtuh menjadi satu dengan dua X.

Dengan kata lain, beberapa set objek yang dibuat secara implisit hanya mungkin ketika tidak ada pengamatan yang cukup dalam program untuk membedakan validitasnya. Jika ada cara untuk membedakan, maka menurut definisi, semuanya tidak akan valid.

Barry
sumber
Ini hanya tebakan saya saja.
Barry
Jadi saya menganggap bahwa tidak ada cara untuk membedakan / mengamati keberadaan atau tidak adanya objek dari berbagai jenis seumur hidup implisit tanpa perilaku yang tidak ditentukan. Dalam kasus itu, bagi saya tampaknya itu adalah satu-satunya penggunaan " perilaku tidak spesifik " dalam standar yang tidak dapat benar-benar mengarah pada hasil yang berbeda yang dapat diamati.
walnut
1
Atau bagaimana jika satu-satunya akses yang melalui glvalues tipe [cv] char, unsigned charatau std::byte? Objek jenis apa pun yang dapat disalin secara sepele juga bisa ada di sana, kurasa?
aschepler
2
Bahkan dalam contoh asli, juga dimungkinkan untuk membuat objek array bersama dengan satu Xobjek.
TC