7

Tôi đang sử dụng một destructor inplace trong mã của tôi, tương tự như sau lột xuống đoạn mã:C++ destructor inplace biên dịch cảnh báo

#include <new> 
#include <stdlib.h> 

struct Node { 
}; 

int main(int, char**) { 
    Node* a = reinterpret_cast<Node*>(malloc(sizeof(Node))); 
    new(a) Node; 

    Node* b = a; 
    b->~Node(); 

    free(a); 
} 

Thật không may này mang lại cho tôi một lời cảnh báo trong Visual Studio 2015, cả trong Debug và Release :

warning C4189: 'b': local variable is initialized but not referenced

Nó biên dịch tốt mặc dù trong g ++, ngay cả với Wall. Bất kỳ ý tưởng tại sao tôi nhận được cảnh báo? Có thể đây là một lỗi trong trình biên dịch? b được sử dụng rõ ràng trong cuộc gọi b->~Node().

Nó cũng dường như biên dịch tốt khi tôi thay đổi việc thực hiện Node này:

struct Node { 
    ~Node() { 
    } 
}; 

Nhưng như xa như tôi có thể nói điều này không nên tạo sự khác biệt.

+1

Hmm, tôi đoán là trình tối ưu hóa sẽ bỏ qua cuộc gọi đến trình phá hủy mặc định hoàn toàn, và sau đó kết luận rằng 'b' không bao giờ được sử dụng. Bạn có thấy cảnh báo này chỉ khi bạn biên dịch một bản dựng được tối ưu hóa hoặc bạn có thấy nó trong các bản dựng chưa được tối ưu hóa/gỡ lỗi không? –

+0

Nó cũng nằm trong bản dựng lỗi – martinus

+0

Thú vị. Vâng, tôi repro với trình tối ưu hóa được kích hoạt và vô hiệu hóa, cho cả hai 32-bit và 64-bit xây dựng, và trên VS 2010, 2012, và 2015. Trông giống như một lỗi cho tôi, trừ khi tôi cũng thiếu một cái gì đó rõ ràng. (Nó * là * eliding cuộc gọi đến destructor trong xây dựng tối ưu, tất nhiên, và trên thực tế, cũng eliding cuộc gọi đến constructor. Mã đối tượng chỉ gọi 'malloc' và' free'.) –

Trả lời

2

Không có tiêu chuẩn cho cảnh báo trình biên dịch trong C++. Do đó mỗi trình biên dịch có thể cảnh báo bạn bất cứ nơi nào anh ta muốn, nó là vấn đề được lựa chọn.

Trong trường hợp của bạn cảnh báo có ý nghĩa, vì destructor mặc định có thể không coi như tham chiếu (ví dụ: tất cả biến cục bộ được hủy mặc định ở cuối phạm vi của chúng).

2

Trivial destructor

Destructor cho lớp T là tầm thường nếu tất cả những điều sau đây là đúng:

  • Destructor không dùng cung cấp (có nghĩa là, nó là một trong hai ngầm tuyên bố, hoặc một cách rõ ràng định nghĩa là mặc định trên khai báo đầu tiên của nó)
  • Trình phá hủy không phải là ảo (nghĩa là, trình phá hủy lớp cơ sở không phải là ảo)
  • Tất cả các lớp cơ sở trực tiếp có destructors tầm thường
  • Tất cả các thành viên dữ liệu không tĩnh của loại lớp (hoặc mảng loại lớp) đều có các trình phá hủy tầm thường.

Trình phá hủy tầm thường là trình hủy không thực hiện hành động nào. Đối tượng với destructors tầm thường không yêu cầu một biểu thức xóa và có thể được xử lý bằng cách đơn giản deallocating lưu trữ của họ.

Các vấn đề liên quan