สามารถมีวัตถุโดยปริยายที่แตกต่างกันตามการตัดสินใจรันไทม์ในภายหลังใน C ++ 20 ได้หรือไม่


11

คำถามนี้หมายถึงการเพิ่มP0593ให้กับC ++ 20 ฉบับร่างล่าสุด

นี่คือตัวอย่างของฉัน:

#include <cstdlib>
#include <cstdio>

void foo(void *p)
{
    if ( std::getchar() == 'i' )
    {
        *(int *)p = 2;
        std::printf("%d\n", *(int *)p);
    }
    else
    {
        *(float *)p = 2;
        std::printf("%f\n", *(float *)p);
    }
}

int main()
{
    void *a = std::malloc( sizeof(int) + sizeof(float) );
    if ( !a ) return EXIT_FAILURE;

    foo(a);
    // foo(a);    [2]
}

รหัสนี้มีการกำหนดที่ดีสำหรับอินพุตทั้งหมดภายใต้ร่างล่าสุดหรือไม่

เหตุผลที่แสดงใน P0593 ทำให้ชัดเจนว่าการไม่ใส่ความคิดเห็น[2]จะนำไปสู่พฤติกรรมที่ไม่ได้กำหนดเนื่องจากการละเมิดนามแฝงที่เข้มงวดหากรายการอินพุตผู้ใช้สองรายการแตกต่างกัน การสร้างวัตถุโดยปริยายน่าจะเกิดขึ้นเพียงครั้งเดียว ณ จุดที่malloc; fooมันไม่ได้ถูกเรียกโดยคำสั่งที่ได้รับมอบหมายใน

สำหรับการรันโปรแกรมใด ๆ ที่เกิดขึ้นจริงจะมีสมาชิกของชุดออบเจ็กต์ทางอ้อมที่ไม่ระบุรายละเอียดซึ่งจะทำให้โปรแกรมมีความชัดเจน แต่ฉันยังไม่ชัดเจนว่าต้องเลือกการสร้างวัตถุโดยปริยายที่กล่าวถึงใน [intro.object] / 10 เมื่อmallocเกิดเหตุการณ์ขึ้นหรือไม่ หรือการตัดสินใจสามารถ "เดินทางข้ามเวลา"

ปัญหาเดียวกันอาจเกิดขึ้นสำหรับโปรแกรมที่อ่านไบนารีบล็อบลงในบัฟเฟอร์จากนั้นทำการตัดสินใจรันไทม์ของวิธีการเข้าถึง (เช่นการดีซีเรียลไลเซชัน

คำตอบ:


9

การสร้างวัตถุโดยปริยายน่าจะเกิดขึ้นเพียงครั้งเดียว ณ จุดที่malloc; fooมันไม่ได้ถูกเรียกโดยคำสั่งที่ได้รับมอบหมายใน

นั่นไม่เกี่ยวข้อง สิ่งที่สำคัญคือวัตถุใดที่ถูกสร้างขึ้น มาตรฐานบอกว่าวัตถุที่ถูกสร้างขึ้นนั้นเป็นสิ่งที่ทำให้ UB เป็นรหัสที่กำหนดอย่างดี:

การดำเนินการนั้นจะสร้างและเริ่มต้นอายุการใช้งานของวัตถุศูนย์หรือชนิดของ implicit-ตลอดอายุการใช้งาน ([basic.types]) ในพื้นที่เก็บข้อมูลที่ระบุหากทำเช่นนั้นจะส่งผลให้โปรแกรมมีพฤติกรรมที่กำหนดไว้

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

ดังนั้นตำแหน่งของการสร้างจึงเป็น "การดำเนินการ" เสมอ แต่การกำหนดสิ่งที่ถูกสร้างขึ้นจะขึ้นอยู่กับวิธีการใช้หน่วยความจำที่รันไทม์ (เช่น: พฤติกรรม)


2
เพื่อความชัดเจนคุณกำลังบอกว่ารหัสของฉันมีการกำหนดดีหรือไม่?
MM

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