Tại sao người ta muốn tắt cảnh báo trình biên dịch?


26

Câu trả lời này và các ý kiến ​​được thêm vào cho thấy một cách để vô hiệu hóa một số cảnh báo của trình biên dịch bằng cách sử dụng #pragmacác lệnh.

Tại sao một người muốn làm điều đó? Thông thường các cảnh báo là có lý do và tôi luôn cảm thấy đó là những lý do chính đáng. Có "trường hợp hợp lệ" nào trong đó cảnh báo nên bị vô hiệu hóa không? Ngay bây giờ tôi không thể nghĩ ra bất kỳ điều gì, nhưng có lẽ đó chỉ là tôi.


4
Không chắc chắn tại sao ai đó đánh dấu này cho gần. Có vẻ như một câu hỏi hợp lý nổi bật với tôi. +1

@Alastair Pitts: Tôi đã đề xuất một di chuyển cho các lập trình viên. Tôi nhận ra sai lầm của mình sau này.
Tugrul Ates

3
Các thông báo cảnh báo là có lý do, vâng, nhưng cũng có một lý do tại sao chúng không phải là thông báo lỗi .
Solomon chậm

2
@jameslarge Nhận xét của bạn tổng hợp tình huống độc đáo. Một cảnh báo là trình biên dịch cho bạn biết rằng một tình huống là hoàn toàn sai , điều này có nghĩa là có thể đúng . Nếu nó chắc chắn sai thì đó là một lỗi. Vì một số cảnh báo có thể là dương tính giả, nên luôn có cách viết mã sao cho loại bỏ cảnh báo. Thật không may, đôi khi cách thực dụng nhất để làm như vậy là thông qua một pragma; do đó tên.
Eric Lippert

Nó không vô hiệu hóa, nó đang ẩn. Vấn đề sẽ vẫn còn đó chỉ là bạn sẽ không thấy nó như vậy
Sisir

Câu trả lời:


11

Tôi chỉ từng có một tình huống mà tôi vô hiệu hóa một cảnh báo. Tôi xem xét các lỗi cảnh báo vì vậy tôi thường không phát hành với các cảnh báo. Tuy nhiên, trong khi phát triển API cho khách hàng, tôi gặp phải vấn đề là một phương pháp cần thiết trong giai đoạn di chuyển bởi một ứng dụng và không nên sử dụng bất kỳ ứng dụng nào khác trong thư viện.

Cách tốt nhất tôi có thể tìm thấy để nói với tất cả người dùng API rằng họ không nên gọi phương thức này là đánh dấu nó đã lỗi thời. Tuy nhiên, điều đó có nghĩa là một trường hợp sử dụng hợp lệ được đánh dấu là một cảnh báo biên dịch.

Eric Lippert đã viết một vài bài đăng về các cảnh báo nơi bạn sẽ tìm thấy thông tin về cách nhóm biên dịch nghĩ về các cảnh báo.

Các trường nội bộ của các loại nội bộ

Không sử dụng chỉ thị không được đánh dấu bằng cảnh báo


10

Dưới đây là một vài cảnh báo trong đó tài liệu đưa ra lý do tại sao bạn có thể muốn tắt chúng:

Các ví dụ khác bao gồm các cảnh báo về việc sử dụng các phương pháp khấu hao nếu bạn biết bạn vẫn muốn sử dụng phương thức cũ hoặc có các thành viên riêng không bao giờ đọc cục bộ, nhưng thay vào đó là sự phản ánh.

Theo kinh nghiệm của tôi, C # ít cần phải vô hiệu hóa các cảnh báo hơn các ngôn ngữ khác như C ++. Điều này phần lớn là vì, như Eric Lippert nói trong blog của mình , họ "cố gắng dành những cảnh báo cho những tình huống mà chúng ta có thể nói gần như chắc chắn rằng mã bị hỏng, gây hiểu lầm hoặc vô dụng."


3
Tốt đẹp. Tôi nghĩ rằng cái đầu tiên là rõ ràng nhất, bởi vì nó cung cấp một trường hợp rất cụ thể một justificaiton (ví dụ thứ ba, cho thấy một đoạn mã sẽ không bao giờ vượt qua đánh giá về nhóm của tôi). Câu hỏi này nói về những cảnh báo lỗi thời / lỗi thời. Về cơ bản, chúng vẫn cần thiết trong mã kế thừa, nhưng bạn muốn không khuyến khích bất kỳ mã mới nào sử dụng chúng. Các mã di sản nên có các cảnh báo bị đàn áp.
Greg Jackson

Tôi đã thực hiện rất nhiều chương trình macro trong excel và tôi đã phải vô hiệu hóa các cảnh báo vì nhiều lý do như tự động lưu, thoát tự động, thông báo, v.v ... Tất nhiên bạn có thể không biết về những cảnh báo này ...
Dave Mess

@ICR Tôi không nhớ việc tắt các cảnh báo trình biên dịch trong Java. Tất cả tôi làm là tránh sử dụng các phương pháp không dùng nữa.
Mahmoud Hossam

@Mahmoud Tôi rất thường thấy mình phải thay thế các cảnh báo "không được kiểm soát" khi làm bất cứ điều gì thậm chí từ xa phức tạp với thuốc generic. Nhưng có lẽ không công bằng khi gộp Java với C ++ trên mặt trận cảnh báo nực cười - đã chỉnh sửa câu trả lời của tôi.
ICR

@ICR Java thực thi việc sử dụng thuốc generic để cung cấp sự an toàn kiểu trong các bộ sưu tập, trong khi một số người coi đây là một hạn chế, tôi nghĩ nó là một tính năng, nó làm cho việc viết mã hơi đau, nhưng nó tiết kiệm cuộc sống và vâng, đầu ra của trình biên dịch C ++ là hơi đáng sợ khi nói đến STL hoặc bất cứ điều gì với các mẫu.
Mahmoud Hossam

8

Một ví dụ trong C mà tôi gặp phải các biến thể thường xuyên:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

Đối số chỉ có liên quan trên một số nền tảng, nhưng trên các nền tảng không liên quan, trình biên dịch của tôi sẽ khiếu nại và vì tôi đã cảnh báo chuyển đổi thành lỗi nên nó sẽ ngăn không cho nó xây dựng.

Chuyển đổi cảnh báo thành lỗi khá nhiều đòi hỏi một lối thoát cho "không phải cái này, tôi biết rõ hơn trình biên dịch trong trường hợp này".


6

Nhiều thư viện Java không thể thiếu chưa bao giờ được cập nhật để loại bỏ nhu cầu về các kiểu chữ không an toàn. Việc ngăn chặn những cảnh báo đó là cần thiết để những cảnh báo quan trọng khác sẽ được chú ý và sửa chữa.


5

Tôi thực hiện công việc nhúng và dường như tôi nhớ một hoặc hai lần khi tôi vô hiệu hóa các cảnh báo vì tôi đang làm một cái gì đó trông vô dụng với trình biên dịch, nhưng thực sự có hiệu ứng trong thế giới thực trong phần cứng.

Lần khác là khi tôi làm việc trên các cơ sở mã với các ý tưởng khác nhau về một số cấu trúc dữ liệu (như cách biểu diễn các mảng byte - char hoặc unsign char?). Trong những trường hợp này, tôi có thể vô hiệu hóa các cảnh báo vì giải pháp thay thế là dành nhiều ngày để duyệt mã và sửa đổi một phần hoặc đưa vào hàng trăm phôi.


3

Có khá nhiều lý do để vô hiệu hóa có chọn lọc các cảnh báo của trình biên dịch, ngay cả đối với các dự án cố gắng thực hành tốt nhất.

  • Trình biên dịch khác nhau (hoặc các phiên bản khác nhau của cùng một trình biên dịch) :
    Trình biên dịch xử lý các cảnh báo theo các cách khác nhau tinh tế. Đưa ra các cảnh báo dương tính giả không ảnh hưởng đến các trình biên dịch khác. Trong trường hợp này, có thể vô hiệu hóa cảnh báo cho các trình biên dịch đó, thay vì chỉnh sửa mã hợp lệ để tắt cảnh báo dương tính giả chỉ ảnh hưởng đến một số trình biên dịch nhất định, đặc biệt là đối với các trình biên dịch cũ cuối cùng sẽ không được hỗ trợ.
  • Với mã được tạo:
    Một số cảnh báo liên quan đến vệ sinh mã (mã chết, nội dung trùng lặp của câu lệnh điều kiện, so sánh vượt quá giới hạn loại) có thể được bỏ qua một cách an toàn vì chúng vô hại và trình biên dịch sẽ tối ưu hóa chúng.
    Tạo mã không đưa ra các cảnh báo vô hại này tất nhiên cũng là một lựa chọn, nhưng có thể rắc rối hơn giá trị của nó.
  • Cảnh báo cho mã bên ngoài:
    Có lẽ bạn sử dụng triển khai tổng kiểm tra qsort hoặc md5 nổi tiếng được bao gồm trong dự án của bạn. Mã được sử dụng bởi nhiều dự án và được biết là hoạt động tốt, tuy nhiên có thể có một số cảnh báo kén chọn mà thông thường bạn sửa cho mã của riêng bạn.
    Tuy nhiên, đối với mã bên ngoài, có thể ít rắc rối hơn khi chỉ vô hiệu hóa cảnh báo (giả sử chắc chắn vô hại).
  • Cảnh báo gây ra bởi các tiêu đề hệ thống:
    Mặc dù hỗ trợ GCC / Clang chẳng hạn -isystem, có những trường hợp khi sự khác biệt trong các tiêu đề hệ thống gây ra các cảnh báo có thể bị bỏ qua (có lẽ một chức năng có giá trị trả về được ký trên một hệ thống chứ không phải một hệ thống khác), gây ra -Wsign-comparecảnh báo.
    Một trường hợp khác có thể là macro được xác định trong tiêu đề hệ thống, bạn có thể sao chép-dán macro vào mã của riêng mình để sửa đổi chúng, nhưng tất cả mọi thứ đều tốt hơn là không phải lo lắng về việc duy trì macro từ thư viện của bên thứ 3 ... vì vậy tốt hơn hết là để làm im lặng cảnh báo (có lẽ macro bỏ lỡ một diễn viên gây ra, -Wsign-conversionvd).
  • Các cảnh báo không được sử dụng trong mã sơ khai:
    Bạn có thể cảnh báo các tham số không được sử dụng, tuy nhiên khi bỏ toàn bộ thư viện trong một tệp chỉ chứa các hàm còn sơ khai - không hữu ích trong việc ép buộc (void)arg1; (void)arg2; (void)arg3; ...trong cơ thể của mọi chức năng còn sơ khai.
    Tốt hơn chỉ nên đàn áp -Wunused-parametertrong trường hợp này.

Lưu ý rằng trong tất cả các ví dụ này, nó giả định vô hiệu hóa các cảnh báo sẽ không che giấu lỗi thật, ví dụ như: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, có lẽ -Wpedantic... và rằng bạn biết những gì bạn đang làm!


2

Hợp lệ hay không, đôi khi được thực hiện để bỏ qua chỉ thị "coi cảnh báo là lỗi" trên máy chủ xây dựng.

Ngoài ra tôi không thể nghĩ ra cái nào cả. Các cảnh báo bị vô hiệu hóa thường là dấu hiệu của một "hax xấu xí" ...


2

Lần trước chúng tôi đã vô hiệu hóa một số cảnh báo nhất định, đó là vì một nhân viên thực tập đã để lại cho chúng tôi mã xấu. Tôi đã làm cho nó hoạt động tốt hơn rất nhiều, với các ranh giới chuyển đổi rõ ràng thay thế cho biểu diễn dữ liệu hỗn loạn.

Trong khi đó, chúng tôi cần phải biên dịch nó và chúng tôi muốn tùy chọn "cảnh báo là lỗi", vì vậy chúng tôi đã loại bỏ một số cảnh báo.


2

Hiện tại, cảnh báo duy nhất tôi từng bỏ qua là

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Bởi vì microsoft không triển khai đặc tả C ++ (tài liệu thậm chí nói rằng họ không!) Và cho phép các hàm khai báo các cú ném cụ thể và tất cả các hàm chỉ có thể ném throw () hoặc throw (...), tức là không có gì hoặc mọi thứ.

Từ HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
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.