ลำดับการดำเนินการของตัวดำเนินการใหม่และอาร์กิวเมนต์ของตัวสร้าง


9

ไม่ c ++ spec ระบุลำดับoperator newและคอนสตรัคของในA กรัม ++ ให้การสั่งซื้อจะ-> -> แต่เสียงดังกราว ++ ให้มันเป็น-> -> ความแตกต่างเกิดจากพฤติกรรมที่ไม่ระบุหรือไม่?new C(A())
A()newC()newA()C()

g ++: 7.4.0 clang ++: 10.0.0

#include <iostream>
#include <cstdlib>

struct A {
    A() {
        std::cout << "call A()\n";
    }
};

struct C {
    C(A) {
        std::cout << "call S()\n";
    }

    void *operator new(size_t s) {
        std::cout << "call new()\n";
        return malloc(s);
    }
};

int main() {
    void *p = new C(A());
}

3
คุณสร้างเป็น C ++ 17, C ++ 14 หรือเก่ากว่าหรือไม่
StoryTeller - Unslander Monica

4
หมายเหตุสองประการ: คุณติดแท็กด้วย "C" ซึ่งแสดงให้เห็นอย่างชัดเจนว่าคุณไม่ได้อ่านคำอธิบายของแท็กนั้น อย่า ตอนนี้คุณถามเกี่ยวกับ "พฤติกรรมที่ไม่ได้กำหนด" (UB) นี่เป็นคำที่ใช้โดยมาตรฐาน C ++ เพื่อทำเครื่องหมายสิ่งที่อาจเกิดอะไรขึ้นและควรหลีกเลี่ยง นอกจากนี้ยังมี "พฤติกรรมที่ไม่ระบุ" ซึ่งอาจใกล้เคียงกับสิ่งที่คุณอยู่หลังจากนั้นเพราะรหัสนั้นดีในทางเทคนิคและไม่ทำให้ UB
Ulrich Eckhardt

1
@Ulrich Eckhardt ขอบคุณคำแนะนำของคุณ ฉันผสมสองคน
kuo

คำตอบ:


11

เสียงดังกราวถูกต้อง ตั้งแต่ C ++ 17 รับประกันการดำเนินการตามคำสั่ง [expr.new] / 19

การเรียกใช้ฟังก์ชันการจัดสรรนั้นถูกจัดลำดับก่อนการประเมินผลของนิพจน์ในเครื่องมือเริ่มต้นใหม่

operator new(ฟังก์ชั่นการจัดสรร) ควรจะเรียกใช้ในตอนแรกจากนั้นการประเมินผลของการแสดงออกใน new-initializer (เช่นA())

ก่อน C ++ 17 คำสั่งซื้อจะไม่รับประกัน [expr.new] / 18 (C ++ 14)

การเรียกใช้ฟังก์ชั่นการจัดสรรนั้นมีการจัดลำดับอย่างไม่แน่นอนตามการประเมินผลของนิพจน์ในตัวกำหนดค่าเริ่มต้นใหม่


ดูเหมือนว่า gcc จะไม่สอดคล้องกับ C ++ 17 (และใหม่กว่า); การคอมไพล์ด้วยgcc10 ในโหมด C ++ 2aให้ผลลัพธ์เหมือนกัน

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