Làm thế nào để đối phó với các cảnh báo trong một dự án cũ


9

Tôi làm việc trong một dự án C ++ tạo ra các cảnh báo. Hầu hết các cảnh báo xuất hiện sau khi mã được viết:

  • Ban đầu dự án sử dụng Visual C ++ 8, sớm chuyển sang 9, nhưng có rất ít sự khác biệt trong các cảnh báo được tạo. Các cảnh báo được cố định hoặc im lặng, do đó không có cảnh báo nào sau đó.
  • Sau đó, một mục tiêu 64 bit đã được thêm vào. Nó tạo ra một số lượng lớn các cảnh báo, chủ yếu là do sử dụng các loại cẩu thả (ví dụ unsignedso với size_t). Không ai làm phiền, hoặc có thời gian, để sửa chúng một khi mã hoạt động đúng mục đích.
  • Sau đó, hỗ trợ cho các nền tảng khác sử dụng GCC (4.5 và 4.6, một số 4.4 ban đầu) đã được thêm vào. GCC kén chọn hơn nhiều, vì vậy nó tạo ra nhiều cảnh báo hơn. Một lần nữa không ai làm phiền, hoặc có thời gian, để sửa chúng. Điều này rất phức tạp bởi thực tế là GCC đã không có một pragma để im lặng cảnh báo bằng một đoạn mã cụ thể cho đến ngày 4.5, và theo tài liệu thì nó vẫn không phải là thứ người ta cần.
  • Trong thời gian đó, một số cảnh báo không được chấp nhận đã xuất hiện.

Vì vậy, bây giờ chúng tôi có một dự án tạo ra hàng ngàn cảnh báo. Và tôi thậm chí không thể nói từ bao nhiêu nơi, vì .cppcác tệp thậm chí được biên dịch nhiều lần bởi các trình biên dịch khác nhau và các cảnh báo trong các tiêu đề được in đi in lại.

Có một thực hành tốt nhất để làm sạch một cái gì đó như thế? Hoặc ít nhất một số kinh nghiệm tích cực đối phó với nó?

Câu trả lời:


4

Đừng chạm vào bất kỳ mã kế thừa nào. Tìm cách để đàn áp các cảnh báo cho bây giờ. Việc thực hiện các thay đổi dường như vô hại đối với mã có thể đưa ra các lỗi trong mã mà theo tôi, đã được kiểm tra và tương đối không có lỗi.

Bằng cách loại bỏ tất cả các cảnh báo hiện có trong cơ sở mã, bạn có thể giả vờ có một bảng xếp hạng sạch sẽ. Bất kỳ cảnh báo mới nào được đưa vào mã nên được loại bỏ và khi mã cũ được viết lại, việc thực hiện mới không nên triệt tiêu các cảnh báo.

Mục tiêu của bạn ở đây nên là:

  1. Giảm tỷ lệ tín hiệu / nhiễu. Nếu các nhà phát triển nhìn thấy hàng ngàn thông báo khi họ xây dựng, họ sẽ không nhận thấy rằng chi nhánh chính có các thông báo năm 2004 và chi nhánh của họ có năm 2006.

  2. Đừng giới thiệu thêm bất kỳ lỗi nào. Bằng cách thực hiện các thay đổi vô hại đã nói ở trên, bạn có thể đưa ra các lỗi chưa được khắc phục. Điều này đặc biệt thích hợp khi bạn có hàng ngàn cảnh báo. Ngay cả khi tỷ lệ lỗi của bạn cực kỳ thấp, bạn vẫn có hàng ngàn cơ hội để làm hỏng việc.

  3. Đừng để mã kế thừa hạ thấp tiêu chuẩn của bạn cho mã mới. Chỉ vì các cảnh báo cho một lớp bị chặn không có nghĩa là lớp mới có thể làm như vậy. Cuối cùng, với sự chuyên cần, mã kế thừa sẽ được loại bỏ khỏi cơ sở mã và được thay thế bằng mã mới hơn, không có cảnh báo.


1
+1 "Thực hiện các thay đổi dường như vô hại đối với mã có thể gây ra lỗi trong mã ..." - Mã kế thừa không có khả năng kiểm tra tự động. Những lỗi này sẽ không được tìm thấy.
mattnz

@mattnz: Trên thực tế các bài kiểm tra tự động nhỏ được trải đều trên cả mã kế thừa và mã không kế thừa. Đây là một ứng dụng tương tác, hầu hết không thể được kiểm tra đơn vị một cách hợp lý. Các đơn vị kiểm tra sự cố tồn tại (về hỏng bộ nhớ) trên máy chủ tích hợp liên tục. Đã hơn một năm rồi, nhưng không ai có thể sửa nó vì nó không thể được sao chép dưới trình gỡ lỗi. Và để hữu ích, máy chủ CI sẽ cần lấy một số mẫu dữ liệu để kiểm tra mà chưa bao giờ được thực hiện.
Jan Hudec

1
Bây giờ tập trung vào cách làm im lặng các cảnh báo hiện có một cách hiệu quả mà không làm im lặng bất kỳ cảnh báo tương tự nào trong mã mới.
Jan Hudec

@Jan: bạn có thực sự nói rằng bạn không thể bận tâm sửa chữa một vài bài kiểm tra bạn có không? Trên một diễn đàn lập trình? Có thật không? (SMH)
mattnz

2
@mattnz: Vâng. Bởi vì các bài kiểm tra là vô ích. Và sẽ luôn như vậy. Trong trường hợp phổ biến nhất của hệ thống thông tin doanh nghiệp, kiểm tra tự động là rất tốt, nhưng đối với loại ứng dụng tương tác, chúng tôi mang lại rất ít giá trị mà đôi khi chúng tôi chỉ sử dụng chúng để gỡ lỗi một số chức năng hỗ trợ. Hầu hết các lỗi xảy ra trong mã chỉ có thể được kiểm tra tương tác. Tôi có thể tưởng tượng việc viết một số tự động hóa cho nó, nhưng nó sẽ là rất nhiều công việc tôi không chắc chắn sẽ hiệu quả chi phí.
Jan Hudec

14

Tôi nghĩ rằng các cảnh báo, không được coi là lỗi, là vô ích. Bạn nhận được rất nhiều trong số họ, do đó không ai bận tâm để nhìn vào họ, và họ bỏ lỡ mục đích của họ.

Đề nghị của tôi là sửa tất cả chúng, và bắt đầu coi chúng là lỗi.
Sửa chúng trông đáng sợ, nhưng tôi nghĩ nó có thể được thực hiện. Một lập trình viên giỏi sẽ nhận công việc này sẽ sớm tìm ra cách để đối phó với từng cảnh báo, và sẽ xử lý nó rất máy móc và nhanh chóng.

Chúng tôi đã thực hiện một dự án tương tự trong công ty của tôi và nó đã hoạt động - hiện tại chúng tôi không có cảnh báo nào về phần mã quan trọng đối với chúng tôi và tôi đang nói về hàng ngàn tệp (không biết có bao nhiêu cảnh báo) .

Điều này phải được thực hiện ngay lập tức bằng cách coi các cảnh báo là lỗi. Khi một phần mã của bạn không có cảnh báo, hãy thay đổi cờ biên dịch cho phần này và không để cảnh báo mới nào được nhập. Nếu bạn không làm điều đó, bạn sẽ thấy các cảnh báo mới bật lên như nấm và công việc của bạn sẽ bị lãng phí.

Một mối quan tâm bạn có thể có là giới thiệu các lỗi do sửa lỗi cảnh báo. Điều này đặc biệt có khả năng vì lập trình viên sửa các cảnh báo có thể không biết hầu hết các mã anh ta đang thay đổi. Tuy nhiên, hầu hết các thay đổi sẽ rất an toàn - ví dụ: thêm một nguyên mẫu hàm hoặc ép kiểu.


2
+1: "Tôi nghĩ rằng các cảnh báo, không được coi là lỗi, là vô ích.": Tôi đồng ý, tại sao tôi lại muốn được cảnh báo về điều gì đó không phải là vấn đề?
Giorgio

1
@Giorgio Bởi vì các cảnh báo không nhất thiết phải được sửa chữa, hoặc có thể không có thời gian / tiền để sửa chúng ngay bây giờ. Chúng là một dạng nợ kỹ thuật. Điều đó không có nghĩa là cuối cùng họ không nên bị xử lý, nhưng điều đó cũng có nghĩa là họ không nhất thiết phải bị cuốn dưới tấm thảm. Lựa chọn duy nhất còn lại của bạn là có chúng; họ ở đó để làm cho bạn ngứa, để cuối cùng họ có thể được sửa chữa.
Robert Harvey

1
@Robert Harvey: Tôi hoàn toàn đồng ý với bạn. Rủi ro duy nhất là người ta bắt đầu phớt lờ các cảnh báo và sau một thời gian chúng không khiến bạn ngứa ngáy nữa: Tôi đã thấy các cảnh báo xuất hiện trong nhiều năm trong cùng một dự án và mọi nhà phát triển sẽ nói rằng họ đáng lẽ phải sửa "một thời gian tương lai". Không ai chú ý đến những cảnh báo này nữa: chúng đã trở thành một phần của đầu ra bình thường trong nhật ký xây dựng chính. Tôi không chắc chắn làm thế nào để tránh loại tình huống này.
Giorgio

1
Vấn đề với việc sửa tất cả tâm lý "bây giờ" là dẫn đến sửa lỗi không đúng và mã ít bảo trì hơn - trong C ++, thật đáng ngạc nhiên khi một typecast có thể khiến cảnh báo biến mất một cách dễ dàng, thường xuyên hơn là không làm sai (ví dụ: ký / không dấu cảnh báo). Đó là mã kế thừa nên không có khả năng kiểm tra hồi quy tự động và các thay đổi mã sẽ gây ra lỗi. "Khắc phục tất cả và b.gg.r hậu quả" không phải là phương pháp đúng.
mattnz

@mattnz, Phá mã trong khi sửa cảnh báo thực sự là mối quan tâm chính ở đây. Tuy nhiên, tôi nghĩ không còn cách nào khác - sửa chúng và coi lỗi trong tương lai là lỗi hoặc bỏ qua chúng (và đôi khi tìm thấy lỗi, về điều mà bạn đã được cảnh báo).
ugoren

3

Tôi đã đọc các tiêu chuẩn mã hóa C ++: 101 quy tắc, hướng dẫn và thực tiễn tốt nhất và hướng dẫn thứ hai cho thấy "Biên dịch sạch ở mức cảnh báo cao". Nó nêu ra một số lý do tại sao bạn không muốn có nhiều cảnh báo trong một chương trình và trưởng trong số đó là

  1. Có một vấn đề tiềm ẩn trong mã của bạn.
  2. Nên im lặng, xây dựng thành công và, nếu không, bạn có thể đang thiếu các vấn đề thực sự.
  3. Cảnh báo lành tính bị bỏ qua có thể làm mờ các cảnh báo chỉ ra những nguy hiểm thực sự

Các chương trình biên dịch với các cảnh báo có thể xuất hiện chính xác nhưng có thể có vấn đề thực sự với mã có thể mọc lên tại một số điểm. Tôi sẽ đề nghị phân loại các cảnh báo, cung cấp cho họ mức độ ưu tiên và khi bạn có thời gian, hãy sửa chúng.


+1: cho "Biên dịch dọn dẹp ở mức cảnh báo cao": Tôi nghĩ chúng ta nên sử dụng càng nhiều trợ giúp từ trình biên dịch càng tốt.
Giorgio

1

Hoặc dành một lần chạy nước rút / chu kỳ để bảo trì phòng ngừa trên hệ thống, xóa mã chết, loại bỏ các cảnh báo, xóa các bình luận xấu, những thứ tương tự, HOẶC đưa ra chính sách loại bỏ các cảnh báo vì dù sao các nguồn cũng bị chạm vào.
Tôi sẽ không làm điều đó trước đây chỉ để loại bỏ các cảnh báo, nhưng nếu một chu trình như vậy được lên kế hoạch thì đó sẽ là một phần của khối lượng công việc. Lý do cho điều đó là việc chạm vào một tệp cho bất kỳ điều gì đều có nguy cơ lỗi và do đó có nguy cơ gây ra sự ổn định của sản phẩm của bạn.


2
Chúng tôi không thể đủ khả năng để dành một cuộc chạy nước rút. Vì vậy, loại bỏ các cảnh báo khi các nguồn được chạm vào vì lý do khác. Nhưng có một số nguồn không được chạm vào trong một thời gian dài và sẽ mất nhiều thời gian cho đến khi họ muốn, vì vậy chúng tôi cần phải nói với các cảnh báo từ các bit kế thừa đó.
Jan Hudec

@JanHudec có thể muốn phân tích mức độ nghiêm trọng của các cảnh báo trong các trường hợp đó, có thể sắp xếp thời gian để xem lại mã cũ đó và dọn sạch các bit được chọn, tái cấu trúc để giữ cho nó tồn tại. Khác nó có thể trở nên cũ kỹ và mọi người sợ chạm vào nó ngay cả khi cần thiết bởi vì không ai còn lại biết làm thế nào nó hoạt động.
jwenting

@JanHudec - Âm thanh như bạn không có thời gian để giải quyết các cảnh báo nếu bạn không đủ khả năng để bảo trì phòng ngừa trên hệ thống.
Ramhound

@Ramhound: Tôi cho rằng chúng ta có thể làm một chút việc gác cổng, nhưng không nhiều và nó phải chạy song song với các công việc khác.
Jan Hudec

1

Tôi cảm thấy nỗi đau của bạn bởi vì tôi đang ở trong một tình huống tương tự. Cách tôi tiếp cận vấn đề là - loại bỏ các cảnh báo một mô-đun / tiểu dự án tại thời điểm đó và đặt cờ trình biên dịch "coi cảnh báo là lỗi" (Werr) cho mô-đun sau khi nó được dọn sạch. Ngoài ra, tôi quyết định chỉ tập trung vào một nền tảng, mặc dù chúng tôi xây dựng trên một số hệ điều hành với các trình biên dịch khác nhau. Cuối cùng, đối với các thư viện phần thứ ba mà chúng tôi biên dịch, tôi chỉ cần tắt các cảnh báo.

Tâm trí bạn, loại bỏ một số cảnh báo này nói dễ hơn nhiều so với thực hiện. Chẳng hạn, size_t so với các vấn đề không dấu mà bạn đề cập có thể gây ra tràn số nguyên nếu bạn chỉ tắt tiếng cảnh báo bằng phôi - vì vậy, trong một số trường hợp, bạn thay thế không dấu bằng size_t, trong các trường hợp khác, bạn cần phát hiện tràn trong thời gian chạy. Đó là tất cả từng trường hợp - rất tẻ nhạt và khó khăn.

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.