เหตุใดเราไม่สามารถสร้างวัตถุที่สร้างขึ้นได้เล็กน้อยโดยใช้ malloc หากตัวสร้างปริยายของ trivial ไม่ทำงาน?


14

ฉันมีปัญหาในการทำความเข้าใจย่อหน้าต่อไปนี้ที่อ้างอิงจากcppreferenceเกี่ยวกับConstructorปริยาย ฉันค้นหา stackoverflow แล้วแต่ยังไม่ได้รับคำตอบที่ชัดเจน ได้โปรดช่วยด้วย

คอนสตรัคค่าเริ่มต้นเล็กน้อยเป็นตัวสร้างที่ไม่มีการดำเนินการ ชนิดข้อมูลทั้งหมดที่เข้ากันได้กับภาษา C (ชนิด POD) สามารถเริ่มต้นสร้างได้เล็กน้อย ซึ่งแตกต่างจากใน C อย่างไรก็ตามวัตถุที่มีตัวสร้างเริ่มต้นเล็กน้อยไม่สามารถสร้างได้โดยการแปลหน่วยความจำที่สอดคล้องกันอย่างเหมาะสมเช่นหน่วยความจำที่จัดสรรด้วย std :: malloc: การจัดวางตำแหน่งใหม่จำเป็นต้องแนะนำวัตถุใหม่อย่างเป็นทางการ

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


งานที่สำคัญที่สุดของคอมไพเลอร์คือการไม่คอมไพล์ซอร์สโค้ด แต่การปฏิเสธโค้ดที่อาจไม่ถูกต้อง ไม่สามารถทำได้เมื่อคุณใช้ malloc ()
ฮันส์

6
เหตุผลง่ายมาก โอกาสที่น้อยลงสำหรับโปรแกรมเมอร์ที่จะทำสิ่งที่บ้าคลั่งยิ่งมีโอกาสมากขึ้นสำหรับผู้เรียบเรียงในการทำสิ่งที่บ้า
n คำสรรพนาม 'm

1
*reinterpret_cast<float*>(&someNonFloatObject) = 0.1f;สำหรับเหตุผลที่คล้ายกันว่าคุณไม่สามารถเพียงแค่ C ++ มีแนวคิดเกี่ยวกับวัตถุและอายุการใช้งานของวัตถุที่ระบุในเครื่องนามธรรมและเพียงเพราะไม่มีคำสั่ง CPU ในการสร้างวัตถุจากที่เก็บข้อมูลไม่ได้หมายความว่าไม่มีความแตกต่างในเครื่องนามธรรม
Max Langhof

1
@HansPassant คอมไพเลอร์ที่ปฏิเสธรหัสทั้งหมดปฏิเสธรหัสที่ไม่ถูกต้องทั้งหมด อย่างไรก็ตามมันไม่ใช่หน้าที่ของ copiler ที่จะปฏิเสธโปรแกรมที่มี UB
n คำสรรพนาม 'm

คำตอบ:


7

P0593R5ให้ตัวอย่างนี้:

struct X { int a, b; };
X *make_x() {
  X *p = (X*)malloc(sizeof(struct X));
  p->a = 1;
  p->b = 2;
  return p;
}

และอธิบาย:

เมื่อคอมไพล์ด้วยคอมไพเลอร์ C ++ รหัสนี้มีพฤติกรรมที่ไม่ได้กำหนดเนื่องจาก p-> ความพยายามในการเขียนไปยัง subobject int ของวัตถุ X และโปรแกรมนี้ไม่เคยสร้างวัตถุ X หรือ subobject int

ต่อ [intro.object] p1

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

... และโปรแกรมนี้ไม่ได้ทำสิ่งเหล่านี้

ในทางปฏิบัติงานนี้และสถานการณ์ของ UB ถือเป็นข้อบกพร่องในมาตรฐานมากกว่าสิ่งอื่นใด วัตถุประสงค์ทั้งหมดของบทความนี้คือการเสนอวิธีการแก้ไขปัญหาและกรณีที่คล้ายคลึงกันโดยไม่ทำลายสิ่งอื่นใด


1

ด้วยเหตุผล "ความบริสุทธิ์"

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

ไม่มีใครเคยสามารถแสดงปัญหาทางตรรกะด้วยการมีวัตถุมากมายในพื้นที่เก็บข้อมูล

เนื่องจากพวกเขามีส่วนต่าง ๆ ของมาตรฐานที่พูดถึงสิ่งที่ขัดแย้งกันสมาชิกคณะกรรมการจึงตัดสินใจที่จะจริงจังกับส่วนที่แย่ที่สุดของมาตรฐาน

นอกจากนี้การใช้ตัวอักษรสตริงไม่ได้รับอนุญาตหากคุณจริงจังกับส่วนหนึ่งของมาตรฐานอย่างจริงจัง


การใช้ตัวอักษรสตริงไม่ได้รับอนุญาตอย่างเคร่งครัดในการกระทำ มีปัญหา CWG ที่คล้ายกันเกี่ยวกับtype_infoวัตถุ คุณเคยรายงาน 'ตัวอักษรสตริงการแข่งขันหรือไม่?
ทนายความภาษา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.