การสร้างวัตถุโดยนัยที่ไม่ระบุ


9

เนื่องจากP0593 การสร้างวัตถุโดยปริยายสำหรับการจัดการวัตถุระดับต่ำได้รับการยอมรับวัตถุจึงอาจถูกสร้างโดยนัยใน C ++ 20

โดยเฉพาะถ้อยคำที่นำโดยข้อเสนอที่จะช่วยให้การดำเนินการบางอย่าง (เช่นstd::malloc) เพื่อสร้างโดยอัตโนมัติและเริ่มต้นชีวิตของวัตถุบางชนิดที่เรียกว่าประเภทนัยชีวิต , ถ้าการแนะนำของวัตถุดังกล่าวจะทำให้โปรแกรมที่มีพฤติกรรมที่ไม่ได้กำหนดไว้เป็นอย่างอื่นที่จะมี พฤติกรรมที่กำหนดไว้ ดู[intro.object] / 10

ตอนนี้ร่างเพิ่มเติมกล่าวว่าหากมีหลายชุดของวัตถุดังกล่าวที่สามารถสร้างขึ้นโดยปริยายเพื่อให้พฤติกรรมที่กำหนดโปรแกรมมันจะไม่ได้ระบุชุดของชุดเหล่านี้จะถูกสร้างขึ้น (ดูเหมือนว่าประโยคที่เกี่ยวข้องจะไม่ปรากฏในการแก้ไขข้อเสนอล่าสุดที่ฉันสามารถเข้าถึงได้ R5 แต่อยู่ในร่างข้อตกลง)

จริง ๆ แล้วมีโปรแกรมที่ตัวเลือกของชุดวัตถุที่สร้างขึ้นโดยปริยายนี้สามารถสังเกตได้หรือไม่? ในคำอื่น ๆ มีโปรแกรมที่มีการกำหนด แต่ไม่ได้ระบุพฤติกรรมผ่านกฎใหม่นี้เช่นว่ามันเป็นไปได้ที่จะอนุมานจากการส่งออกซึ่งชุดประเภทของวัตถุโดยปริยาย (มากกว่าหนึ่งที่เป็นไปได้มากกว่าหนึ่ง) ถูกสร้างขึ้น?

หรือประโยคนี้มีความหมายเพียงเพื่อชี้แจงการดำเนินการของโปรแกรมบนเครื่องนามธรรม (โดยไม่มีผลกระทบที่สังเกตได้)?


2
(OT) หากวัตถุที่สร้างขึ้นโดยปริยายเป็น int เราสามารถเรียกมันว่า "implicit int" ได้หรือไม่?
MM

ดูเหมือนว่าไม่ชัดเจนว่าจะต้องทราบองค์ประกอบทางเลือกจากชุดที่ไม่ระบุที่จุด Malloc
MM

@MM ฉันคิดว่าตัวเลือกของเซตถูกพิจารณาว่าเกิดขึ้นอย่างเป็นนามธรรมเป็นตัวเลือกเดียวสำหรับการดำเนินการโปรแกรมทั้งหมดนอกโฟลว์การดำเนินการ แต่มีการสร้างเกิดขึ้นโดยตรงกับการดำเนินการที่เป็นปัญหา (เช่นstd::malloc) มิฉะนั้นคุณจะพบปัญหากับคำจำกัดความ ขึ้นอยู่กับอนาคต
walnut

ฉันทำคำถามอื่นในหัวข้อที่ stackoverflow.com/questions/60627249 แน่นอนว่ามีข้อพิสูจน์อีกหลายข้อที่จะนึกถึง แต่คำถามหนึ่งข้อต่อครั้ง ..
MM

การเรียกร้องข้อเสนอว่ามันเป็นไปไม่ได้เพื่อให้เห็นความแตกต่างซึ่งเป็นสิ่งสำคัญเนื่องจากมีวิธีการเลือกที่จะทำ“อย่างถูกต้อง” ไม่เพียง แต่เพิ่มประสิทธิภาพเพื่อหลีกเลี่ยงการที่มิฉะนั้นจะ ( มากอย่างเคร่งครัด) ที่ถูกต้อง
Davis Herring

คำตอบ:


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วินาที แต่เขียนถึงหนึ่งในนั้นและไม่มีอะไรในโปรแกรมนี้ที่จะได้สัมผัสส่วนที่เหลือของไบต์ ดังนั้นจึงมีชุดของวัตถุที่แตกต่างกันมากมายที่สามารถสร้างขึ้นโดยปริยาย - อาจเป็นสองXs, อาจXและสองints, อาจXและแปดchars, ...

มันไม่สามารถสังเกตได้ว่าชุดใดถูกสร้างขึ้นเพราะถ้ามีการสังเกตจริง ๆ ใด ๆ มันจะลดความเป็นไปได้ที่จะมีเพียงชุดที่ถูกต้องเท่านั้น หากเราทำอะไรเช่นp[1]->a = 3นี้จักรวาลแห่งความเป็นไปได้ก็จะพังทลายลงเหลือเพียงหนึ่งที่มีสองXs

กล่าวอีกนัยหนึ่งชุดของวัตถุที่สร้างขึ้นโดยปริยายหลายชุดอาจเกิดขึ้นก็ต่อเมื่อโปรแกรมมีข้อสังเกตไม่เพียงพอที่จะแยกแยะความถูกต้อง หากมีวิธีที่จะแยกความแตกต่างจากนั้นโดยนิยามพวกเขาจะไม่ถูกต้องทั้งหมด


นี่เป็นเพียงการคาดเดาของฉัน
Barry

ดังนั้นฉันคิดว่ามันไม่มีวิธีแยกแยะ / สังเกตการมีอยู่หรือการไม่มีอยู่ของวัตถุประเภทต่าง ๆ โดยปริยายตลอดชีวิตโดยไม่มีพฤติกรรมที่ไม่ได้กำหนด ในกรณีนั้นฉันคิดว่าเป็นการใช้ " พฤติกรรมที่ไม่ระบุ " เท่านั้นในมาตรฐานที่ไม่สามารถนำไปสู่ผลลัพธ์ที่สังเกตได้ที่แตกต่างกัน
walnut

1
หรือสิ่งที่ถ้าเพียง แต่มีการเข้าถึงผ่านทาง glvalues ประเภท [CV] char, unsigned charหรือstd::byte? วัตถุชนิดใดก็ได้ที่สามารถคัดลอกได้มีอยู่จริงฉันเดา?
aschepler

2
แม้ในตัวอย่างดั้งเดิมก็เป็นไปได้ที่จะสร้างวัตถุอาร์เรย์พร้อมกับXวัตถุหนึ่งชิ้น
TC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.