2009-02-04 28 views
15

Trong quá khứ tôi đã làm việc với -Wall và các thiết bị chuyển mạch khác cho gcc để loại bỏ mọi cảnh báo trình biên dịch cho các dự án tôi đã tham gia. Tương tự như vậy, trong Perl, tôi luôn lập trình sử dụng cảnh báo nghiêm ngặt và sử dụng (và thường là -T cũng vậy) để cố gắng đạt được chất lượng mã tốt nhất mà tôi có thể. Tôi hiểu rằng một vài năm trước đây, nhóm người khuân vác Perl đã làm việc chăm chỉ để làm cho bản thân perl (thông dịch viên Perl) biên dịch sạch dưới gcc với tất cả các cảnh báo được kích hoạt. Rõ ràng họ cảm thấy đó là một ý tưởng tốt cho chất lượng mã. Tôi cũng hiểu rằng hiện nay các lập trình viên của Perl đã thêm nhiều cảnh báo vào mã của họ với Perl :: Critic, cảnh báo họ khi họ vi phạm các phương pháp hay nhất được tìm thấy trong cuốn sách Perl Best Practices của Damian Conway (và từ các nguồn khác).Bạn có nên loại bỏ cảnh báo trình biên dịch không?

Tôi luôn có cảm giác tốt về mã mà tôi đã dọn dẹp theo cách này, nhưng đôi khi tôi không thể tránh được cảm giác rằng một số công việc đã bị lãng phí một chút. Ví dụ, trong lớp học của tôi giới thiệu C hơn một thập kỷ trước, tôi được dạy để bắt đầu hàm main() của tôi như thế này:

void main(void) { 

Đây là tối thiểu và chỉ có thể được sử dụng khi bạn không được trả lại một giá trị và không truy cập đối số của bạn. Nó hoạt động tốt trong trường hợp đó, nhưng cảnh báo gcc sẽ cho bạn biết rằng chức năng này thực sự nên trông giống như:

int main(int args, char* argv) { 

tôi có lẽ đã gõ một vài trăm args int không sử dụng, char * argv dòng trở lại trong ngày. Tôi đã thực sự làm cho mã của tôi tốt hơn, hoặc chỉ cần đeo ngón tay của tôi xuống ngắn hơn?

Hiện tại tôi đang lập trình bằng Java trong Eclipse và dự án của chúng tôi có hàng chục nghìn cảnh báo. Tôi muốn làm sạch chúng. Một số trong số đó đặc biệt khó hiểu và loại bỏ, nhưng dần dần tôi đang học. Một vài trong số chúng tôi đã phải xử lý với các chỉ thị của trình biên dịch để ngăn chặn các cảnh báo (thường là trong các phương thức tối thiểu nhỏ để đưa ra các hành động không quan tâm của việc bỏ qua các cảnh báo), nhưng tôi cũng đang tìm cách xử lý các cảnh báo đó.

Đây có phải là giá trị của một lập trình viên không? Liệu một dự án có thực sự tốt hơn nhiều nếu bạn theo dõi mọi cảnh báo trình biên dịch đơn lẻ?

Nếu không có gì khác, có vẻ như sẽ tốt hơn nếu giảm số cảnh báo xuống 0 để cảnh báo nghiêm trọng sẽ không bị lạc trong mớ hỗn độn.

Note: Duplicate của this question

+0

hàng chục nghìn cảnh báo ?! Geez, vui vẻ. –

+0

Tìm thấy câu hỏi của bạn vì dự án tôi đang làm gần đây cũng có hàng nghìn cảnh báo. Ngay cả việc xây dựng EAR luôn luôn phun ra 9 cảnh báo (tất cả là về Sun độc quyền API). Tôi bỏ qua chúng nhưng tôi đảm bảo không có cảnh báo trong các phần của mã cá nhân tôi liên lạc (chỉnh sửa hoặc tạo). Phần lớn thời gian, dù thế nào đi chăng nữa. Những người khác làm việc trên dự án không quan tâm đến các cảnh báo ở tất cả (miễn là nó hoạt động, nó là tốt) và nói với nhau để chỉ nhắm mắt làm ngơ trước mọi cảnh báo, chỉ xử lý các lỗi. – ADTC

Trả lời

27

Vâng, chắc chắn. Cảnh báo là dấu hiệu cho thấy có điều gì đó sai trong mã của bạn. Bạn có thể sửa chữa nó hoặc bạn nên tắt cảnh báo - nếu bạn không thực hiện hành động đó, việc cảnh báo chỉ ngăn bạn phát hiện khi có cảnh báo mới xuất hiện.

Cách dễ nhất để nhận và giữ mã không có cảnh báo đơn giản là luôn biên dịch với -Werror (/ WX trong Visual Studio) hoặc tương đương.

1

Nó sẽ lưu trình biên dịch thời gian viết ra các cảnh báo và giúp bạn dễ dàng tìm thấy các cảnh báo nguy hiểm hơn nếu bạn giảm số cảnh báo phù phiếm trong mã của mình. Đó có phải là thời gian cần thiết để truy tìm mọi cảnh báo và khắc phục sự cố không? Không thường xuyên ... nhưng đáng để sửa chữa cảnh báo khi chúng rõ ràng và dễ sửa chữa, hoặc khi bạn cần dành thời gian và thay đổi logic chứa cảnh báo vì một lý do khác.

+0

IMO đáng để sửa chữa tất cả, mọi lúc, vì lý do mà nếu không bạn sẽ không nhất thiết phải chú ý khi có cảnh báo mới (có thể quan trọng hơn) được tạo ra! – mghie

+0

Thời gian cần để trình biên dịch in các cảnh báo là hoàn toàn và hoàn toàn không quan tâm đến vấn đề này. – JesperE

+0

Thời gian cần để trình biên dịch in cảnh báo là thời gian không dành cho việc phát triển.Đối với số lượng cảnh báo thấp và các bản dựng không thường xuyên, điều đó là tầm thường. Nếu bạn có hàng chục nghìn cảnh báo, và xây dựng nhiều lần một ngày ... điều đó sẽ tăng lên. – Illandril

7

Đây có phải là giá trị của một lập trình viên không? Liệu một dự án có thực sự tốt hơn nhiều nếu bạn theo dõi mọi cảnh báo trình biên dịch đơn lẻ?

Có. Ngay cả những điều tầm thường về dấu hiệu không khớp có thể có tác động sâu sắc đến việc tạo và tối ưu hóa mã.

2

Eclipse, IntelliJ và các hệ thống chất lượng mã hiện đại khác có số lượng cảnh báo có sẵn rất lớn.

Dọn dẹp cảnh báo là một phương pháp hữu ích, nếu không có lý do nào khác ngoài việc làm giảm tiếng ồn. Mã của bạn có thể đã có một số trong số đó là những lỗi thực sự.

Tuy nhiên, nhiều cảnh báo có thể không có thật. Một số cảnh báo từ Eclipse là những thứ như tối ưu hóa vi mô hoặc nitpicking kiểu cách. Điều này có nghĩa rằng một số dọn dẹp của bạn phải được tinh chỉnh các thiết lập của công cụ của bạn, thay vì thay đổi mã hoặc chỉ thị đàn áp cục bộ.

1

Ý kiến ​​của tôi. Vâng.

Như bạn đã nói ở cuối. Nó giúp làm cho các lỗi thực sự nổi bật hơn.

Khi bạn chạy tập lệnh cgi Perl xuất ra cảnh báo trên máy chủ Apache, các cảnh báo được ghi vào error.log. Tại sao lãng phí không gian. Khắc phục các cảnh báo.

Ngoài ra, tôi nghĩ đó là trải nghiệm học tập để hiểu rõ hơn về ngôn ngữ và trình biên dịch. Tôi đã không nhận ra phạm vi năng động thậm chí là một tính năng của Perl cho đến khi tôi bắt đầu sử dụng nghiêm ngặt.

6

Có hai nguyên mẫu phù hợp cho chính trong C.

int main(void) 

int main(int argc, char **argv) 

void main(void) là không đúng về mặt kỹ thuật, mặc dù nó có thể được hỗ trợ bởi một số trình biên dịch như một phần mở rộng theo tiêu chuẩn.

Vì vậy, trong trường hợp cụ thể của bạn, bạn có thể sử dụng một tuyên bố ngắn main và, nếu tuân thủ, nó sẽ không kích hoạt cảnh báo.

3

Vâng, làm như vậy ..

Mới hôm qua tôi đã làm điều đó cho một dự án tại nơi làm việc. Trong khi loại bỏ các cảnh báo tôi đã đến về hai vấn đề mà hóa ra là lỗi thực sự.

Đó là một dự án C, và trong một nguồn sqrt (căn bậc hai) được gọi. Tôi nhận được cảnh báo sau đây:

test.c:4: warning: implicit declaration of function 'sqrt' 

Hóa ra rằng các coder quên bao gồm đúng tiêu đề-file và căn bậc hai được gọi với đối số số nguyên, không nổi. Điều này rõ ràng là sai và không phải những gì ông dự định.

Cảnh báo đã ở đó trong một thời gian, nhưng không ai đã nhìn thấy nó bởi vì nó đã bị mất trong 1000 cảnh báo vô hại khác chỉ cuộn trên màn hình. Cảnh báo có lý do.

Btw - sửa các cảnh báo đưa tôi như ... 4 giờ ... Không có gì so với thời gian để viết tất cả nội dung đó.

5

Có. Ngay cả những điều tầm thường cũng đáng để sửa chữa. Đây là lý do tại sao.Một số, như ví dụ về chính bạn đề cập đến, có lẽ không phải là giá trị sửa chữa trên riêng của họ, nhưng họ đang ở trong tổng hợp. Hầu hết các cảnh báo trình biên dịch sẽ giúp bạn giảm đau trực tiếp trong thời gian dài. Chúng là những lỗi đang chờ xảy ra (hoặc thậm chí xảy ra bây giờ). Để tìm những thứ đó, bạn cần một cách dễ dàng để nhận ra chúng. Nếu bạn sửa tất cả các cảnh báo, thì mỗi cảnh báo mới là cờ đỏ và dễ nhận thấy. Nếu bạn khắc phục tất cả những vấn đề quan trọng nhưng chỉ để lại một số vấn đề như "chính", bạn sẽ bỏ lỡ những vấn đề quan trọng mới.

Điều gì dễ nhớ hơn? Đó là bất kỳ cảnh báo cần phải được cố định hoặc bạn có 23 cảnh báo không liên quan trong cơ sở mã này ngày hôm qua và vì vậy nếu bạn thấy 24 bạn cần phải đi xem?

Trong cơ sở mã tôi làm việc trên chúng tôi nói với trình biên dịch để tạo ra lỗi trên tất cả các cảnh báo. Điều này buộc chúng ta phải sửa chúng và giữ mã trong hình dạng tốt hơn nhiều. Nếu có một cảnh báo thực sự không đáng khắc phục, luôn có #pragma để biến nó thành biến mất. Bằng cách đó bạn vẫn có một đường sáng cho thất bại.

1

Ví dụ của bạn là một minh họa hoàn hảo tại sao cảnh báo không nên bỏ qua. void main(void) là một mẫu thử nghiệm không hợp lệ (nhưng int main(void) hoạt động!)) Và mã của bạn có thể bị hỏng trên một số trình biên dịch. Trình biên dịch của bạn đủ tốt để chỉ ra điều này.

Tôi đã nhận thấy rằng hầu hết mỗi cảnh báo thực sự trỏ đến một vấn đề thực sự, ngay cả khi tôi không hiểu nguyên nhân tại thời điểm đó. Về cơ bản, tôi luôn làm một cái gì đó và dự định một cái gì đó khác. Tuy nhiên, hiệu quả có thể đạt được, nhưng chỉ bằng sự trùng hợp ngẫu nhiên.

Coi các cảnh báo là lỗi. Ngoại lệ tồn tại (có một trong các trình biên dịch VB.NET liên quan đến các loại giá trị uninitialized) nhưng cực kỳ hiếm. Và nếu bạn từng vấp phải một trong những ngoại lệ này, bạn sẽ biết nó.

8

Tôi đồng ý với tất cả các câu trả lời mà nói "sửa chữa tất cả chúng", nhưng tôi vẫn muốn trình bày một cái nhìn đối lập:

Có hệ thống kế thừa, nơi một số (nhiều hoặc tất cả) các thành phần là không có một chuyên dụng người bảo trì và các bộ phận lớn của hệ thống về cơ bản là không rõ. Việc sửa lỗi cảnh báo trình biên dịch trong mã không xác định như vậy có thể mất một lượng đáng kể mã (vì mỗi cảnh báo mã cùng với ngữ cảnh của nó cần được hiểu) và giới thiệu một nguồn lỗi có thể xảy ra (một số mã phụ thuộc về hành vi chưa xác định). Và kể từ khi hệ thống di sản như vậy hiếm khi có phạm vi kiểm tra rộng rãi, bạn thậm chí không thể dựa vào các bài kiểm tra để thông báo cho bạn về các hồi quy.

+0

Điểm rất tốt. Việc sửa lỗi cảnh báo trong mã kế thừa sẽ không được thực hiện một cách mù quáng. Có rất nhiều rủi ro liên quan đến việc làm như vậy. –

+0

Đây là một điểm hợp lệ, nhưng tôi nghĩ rằng nếu bạn không muốn sửa đổi mã cũ, bạn nên vô hiệu hóa cảnh báo tương ứng một cách có chọn lọc nhất có thể, tốt nhất là với nhận xét giải thích lý do. Để lại các cảnh báo để gây ô nhiễm đầu ra xây dựng vẫn còn giá trị tránh. – JesperE

4

Tôi sẽ di chuyển đối với gói ở đây và nói rằng có thể có một số cảnh báo trình biên dịch không đáng để sửa. Ví dụ sau:

Chúng tôi có rất nhiều mã được viết trước Java 1.5 và Generics. Nó vẫn làm việc. Eclipse cũng tạo ra hàng nghìn cảnh báo về các bộ sưu tập không được kiểm soát. Thực tế tất cả các bộ sưu tập này bị hạn chế về phạm vi; họ sẽ không bao giờ phá vỡ. Nhưng chờ đợi, bạn có thể yêu cầu; điều gì về một vài bộ sưu tập mà không phải là bị giới hạn về phạm vi? Bạn không mạo hiểm một bộ sưu tập ở đâu đó có chứa một thể hiện của một cái gì đó mà không bao giờ nên đi vào đó?

Câu trả lời là: rất nhiều mã đó cũng không thay đổi. Đó là di sản-ish; không có mã mới nào đang sửa đổi các bộ sưu tập đó và mã đó đã được sử dụng trong nhiều năm mà không có vấn đề gì. Nó vẫn còn trong cơ sở mã của chúng tôi, và chúng tôi sẽ phải duy trì nó nếu một lỗi được biểu hiện, nhưng trong thực tế, nó đã hoàn thành công việc của nó. Chi tiêu thời gian cần thiết để parametrize tất cả những bộ sưu tập chung sẽ mất thời gian trong số các dự án cần thiết khác.

Lưu ý hãy cẩn thận ở đây, sau đó:

  • Mã này đã được sử dụng cho một thời gian dài không có lỗi đã thông báo.
  • Mã không trải qua bất kỳ chỉnh sửa đáng kể nào.

Nếu một trong những điểm dừng là sự thật - chẳng hạn, ví dụ, một lỗi bất ngờ không manifest, và chúng ta phải đi vào và chỉnh sửa - những lời cảnh báo đột nhiên trở nên đáng giá hơn để sửa chữa. (Ngẫu nhiên, chúng cũng rất rẻ tiền để sửa chữa vào thời điểm này, chúng tôi có thể sửa chữa các khối liên quan trên đường đi khi chúng tôi khắc phục lỗi.)

1

Bạn nên luôn cố gắng không có cảnh báo nào xuất hiện khi biên dịch. Bằng cách đó, cảnh báo mới sẽ thu hút sự chú ý. (Kinh nghiệm bực bội nhất của tôi từ trước đến nay là trình biên dịch AIX C++ trở lại vào năm 2002, nó đã phát ra hàng trăm cảnh báo về mã mà thậm chí không có nhiều templated.)

Biết ý nghĩa của từng cảnh báo. Trong trường hợp của bạn, bạn nên nhập tiêu chuẩn int main() thay vì không chính xác void main(void) hoặc clumsier int main(int argc, char **argv). Loại bỏ những gì bạn có thể, và ngăn chặn các cảnh báo bạn đã coi là chấp nhận được.

Bạn có thể không muốn khắc phục mọi cảnh báo. Như sau đó nói, có những hệ thống di sản, nơi sửa chữa cảnh báo là hết sức nguy hiểm, và các hệ thống phức tạp như CGAL nơi bạn không muốn muck với mã hoặc. Khi chuyển đổi các ứng dụng của chúng tôi chạy dưới 64 bit, tôi đã tìm thấy các trường hợp mà tôi có thể loại bỏ cảnh báo chỉ bằng một diễn viên, điều này có khả năng gây ra các sự cố khác. Chúng tôi đã loại bỏ cảnh báo đó.

2

Một lý do khác để đảm bảo rằng mã của bạn biên dịch không có cảnh báo là, nếu ai đó * có để làm cho thay đổi mã tại một số điểm trong tương lai, một nơi tốt để bắt đầu là đảm bảo rằng chúng có thể biên dịch mã trong biểu mẫu hiện tại của nó.

Tuy nhiên, nếu họ thực hiện việc này và thấy nhiều cảnh báo, những cảnh báo này luôn tồn tại hay họ đã cài đặt trình biên dịch không chính xác trên PC của họ?

Ít nhất nếu có quy tắc (và một hộp để đánh dấu vào danh sách kiểm tra, nếu bạn sử dụng một) mã phải biên dịch mà không có cảnh báo, thì bạn tránh sự mơ hồ này.

(* Người khác có thể bao gồm bản thân tương lai của bạn).

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