Trình tự thực hiện của toán tử mới và đối số của hàm tạo


9

Liệu C ++ spec chỉ định thứ tự operator newvà hàm tạo của Ain new C(A()).
G ++ để thứ tự là A()-> new-> C(), nhưng clang ++ hãy để nó là new-> A()-> C().
Là sự khác biệt gây ra bởi hành vi không xác định?

g ++: 7.4.0 tiếng kêu ++: 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
Bạn đang xây dựng như C ++ 17, C ++ 14 hoặc trước đó?
Người kể chuyện - Unslander Monica

4
Hai lưu ý: Bạn đã gắn thẻ này bằng "C", cho thấy rõ bạn không đọc mô tả của thẻ đó. Đừng. Bây giờ, bạn hỏi về "hành vi không xác định" (UB). Đây là một thuật ngữ được sử dụng bởi tiêu chuẩn C ++ để đánh dấu những điều mà bất cứ điều gì có thể xảy ra và cần tránh. Ngoài ra còn có "hành vi không xác định", có lẽ gần với những gì bạn đang theo đuổi, bởi vì mã này về mặt kỹ thuật tốt và không gây ra UB.
Ulrich Eckhardt

1
@Ulrich Eckhardt Cảm ơn đề nghị của bạn. Tôi trộn lẫn hai.
eddie kuo

Câu trả lời:


11

Clang là chính xác. Kể từ C ++ 17, thứ tự thực hiện được đảm bảo. [ví dụ] / 19

Việc gọi hàm phân bổ được sắp xếp theo trình tự trước khi đánh giá các biểu thức trong bộ khởi tạo mới .

operator new(hàm phân bổ) được cho là được gọi trước tiên, sau đó là đánh giá biểu thức trong bộ khởi tạo mới (tức là A()).

Trước C ++ 17, đơn hàng không được đảm bảo. [ví dụ] / 18 (C ++ 14)

Việc gọi hàm phân bổ được sắp xếp không xác định theo trình tự đối với các đánh giá biểu thức trong bộ khởi tạo mới .


Có vẻ như gcc không phù hợp với C ++ 17 (và sau này); biên dịch với gcc10 trong chế độ C ++ 2a cho kết quả tương tự.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.