2013-02-04 20 views
11

C4172 Cảnh báo Visual C++ cho các trường hợp khi hàm trả về địa chỉ của một địa phương hoặc tạm thời hoặc tham chiếu đến biến cục bộ.Có bất kỳ trường hợp nào cảnh báo C4172 Visual C++ không nên được coi là lỗi không?

Something như thế này:

int& fun() 
{ 
    int var; 
    return var; //C4172 
} 

Bây giờ có vẻ như nó là một ý tưởng tốt để sử dụng #pragma warning để làm cho Visual C++ đối xử với C4172 như lỗi và phá vỡ biên dịch.

Có bất kỳ tình huống sane nào mà C4172 không thực sự là lỗi không?

+0

Vì vậy, bạn muốn biết nếu nó không quan trọng để đối xử với nó vĩnh viễn như một lỗi - có nghĩa là: tại sao nó được định nghĩa là một cảnh báo để bắt đầu với? Câu hỏi tuyệt vời. –

+3

Rất có thể không, và trình biên dịch là đúng để cung cấp nó như là một chẩn đoán và không phải là lỗi biên dịch bởi vì nó là hành vi không xác định để trở về tham chiếu đến địa phương và không phải là lỗi cú pháp ngôn ngữ. Tại sao nó không được định nghĩa là lỗi cú pháp ngôn ngữ? Bởi vì nó không phải là một lỗi cú pháp. –

+0

@jim mcnamara: Vâng, bạn nói đúng. – sharptooth

Trả lời

8

Tôi không chắc chắn lý do tại sao bất cứ ai đã bao giờ muốn làm điều này:

int * stackTester() 
{ 
    int dummy; 
    return &dummy; 
} 

bool stackGoesUp() 
{ 
    int dummy; 
    return stackTester() > &dummy; 
} 

Nhưng nói chung, bạn nên đối xử với những cảnh báo như một lỗi.

+0

Một ví dụ đơn giản hơn một chút: tìm hiểu xem một khung stack tối thiểu lớn cỡ nào (= size of return address?) –

+4

Nếu tôi hiểu tiêu chuẩn C, so sánh con trỏ với>, <, > = và <= results undefined behavior nếu các con trỏ không trỏ vào cùng một đối tượng tổng hợp (struct/union) hoặc các phần tử của cùng một mảng (bao gồm phần tử không tồn tại sau phần tử cuối cùng). Tôi nghĩ C++ là như nhau ở đây. –

+1

@AlexeyFrunze: Đúng, * nhưng * 'std :: less ' được định nghĩa cho con trỏ, ngay cả khi chúng không trỏ đến các phần tử của cùng một mảng. –

4

Đây là cảnh báo cấp 1, rất khó bỏ qua. Nhưng trình biên dịch theo tiêu chuẩn ngôn ngữ ở đây, gọi UB là không bị cấm. Và nó là một lỗi rất phổ biến mà thường xuyên đến một kết thúc tốt đẹp. Vị trí ngăn xếp được trỏ đến vẫn ổn định miễn là bạn không thực hiện bất kỳ cuộc gọi chức năng nào.

Cách tốt nhất để giải quyết vấn đề này là luôn luôn biến cảnh báo thành lỗi. Biên dịch với/WX, "Hãy coi cảnh báo là lỗi" trong IDE. Nếu sau đó bạn cố ý muốn ngăn chặn một cảnh báo thì cảnh báo #pragma làm cho mọi người biết rằng có điều gì đó đáng sợ đang xảy ra và không phải là một tai nạn.

0

mã không sử dụng

class base 
{ 
    virtual blah& makeBlah() 
} 

class red : public base 
{ 
    blah& makeBlah() { return blah(); } // there are no red blahs, never called 
} 

class blue : public base 
{ 
    blah& makeBlah() { actual code to make a blah } 
} 
Các vấn đề liên quan