เสียงสัญญาณเตือนดังกราวสำหรับการพัฒนา Objective-C


86

ในฐานะโปรแกรมเมอร์ C & Objective-C ฉันรู้สึกหวาดระแวงเล็กน้อยกับแฟล็กการเตือนของคอมไพเลอร์
ฉันมักจะพยายามค้นหารายการคำเตือนทั้งหมดสำหรับคอมไพเลอร์ที่ฉันใช้และเปิดใช้งานส่วนใหญ่ยกเว้นว่าฉันมีเหตุผลที่ดีจริง ๆ ที่จะไม่เปิดใช้งาน

โดยส่วนตัวฉันคิดว่าสิ่งนี้อาจช่วยพัฒนาทักษะการเขียนโค้ดรวมถึงการพกพาโค้ดที่อาจเกิดขึ้นป้องกันปัญหาบางอย่างเนื่องจากมันบังคับให้คุณระวังทุกรายละเอียดเล็กน้อยการใช้งานที่อาจเกิดขึ้นและปัญหาด้านสถาปัตยกรรมและอื่น ๆ ...

มันเป็นความคิดของฉันเป็นเครื่องมือการเรียนรู้ที่ดีทุกวันแม้ว่าคุณจะเป็นโปรแกรมเมอร์ที่มีประสบการณ์

สำหรับส่วนที่เป็นอัตนัยของคำถามนี้ฉันสนใจที่จะได้ยินนักพัฒนาอื่น ๆ (ส่วนใหญ่ C, Objective-C และ C ++) เกี่ยวกับหัวข้อนี้
คุณสนใจเกี่ยวกับสิ่งต่าง ๆ เช่นคำเตือนเกี่ยวกับเด็ก ๆ หรือไม่? และถ้าใช่หรือไม่ใช่ทำไม

ตอนนี้เกี่ยวกับ Objective-C ฉันเพิ่งเปลี่ยนมาใช้LLVM toolchain (กับ Clang) แทน GCC

ในรหัสการผลิตของฉันฉันมักจะตั้งค่าสถานะการเตือนนี้ (ชัดเจนแม้ว่าบางคนอาจจะครอบคลุมโดย -Wall):

  • -ผนัง
  • -Wbad ฟังก์ชั่หล่อ
  • -Wcast ชิด
  • -Wconversion
  • -Wdeclaration หลังจากคำสั่ง
  • -Wdeprecated-การใช้งาน
  • -Wextra
  • -Wfloat เท่ากับ
  • -Wformat = 2
  • -Wformat-nonliteral
  • -Wfour-ถ่านคงที่
  • -Wimplicit อะตอม-คุณสมบัติ
  • -Wmissing วงเล็บ
  • -Wmissing-ประกาศ
  • -Wmissing สนาม-initializers
  • -Wmissing รูปแบบแอตทริบิวต์
  • -Wmissing-noreturn
  • -Wmissing ต้นแบบ
  • -Wnested-externs
  • -Wnewline-EOF
  • -Wold แบบละเอียด
  • -Woverlength สตริง
  • -Wparentheses
  • -Wpointer-ARITH
  • -Wredundant-decls
  • -Wreturn ชนิด
  • -Wsequence จุด
  • -Wshadow
  • -Wshorten-64 ต่อ 32
  • -Wsign-เปรียบเทียบ
  • -Wsign แปลง
  • -Wstrict ต้นแบบ
  • -Wstrict เลือกการแข่งขัน
  • -Wswitch
  • -Wswitch เริ่มต้น
  • -Wswitch-enum
  • -Wundeclared เลือก
  • -Wuninitialized
  • -Wunknown-pragmas
  • -Wunreachable รหัส
  • -Wunused ฟังก์ชั่น
  • -Wunused ฉลาก
  • -Wunused พารามิเตอร์
  • -Wunused มูลค่า
  • -Wunused ตัวแปร
  • -Wwrite สตริง

ฉันสนใจที่จะได้ยินว่านักพัฒนาคนอื่นพูดถึงเรื่องนี้อย่างไร

ตัวอย่างเช่นคุณคิดว่าฉันพลาดการตั้งค่าสถานะเฉพาะสำหรับ Clang (Objective-C) และทำไม
หรือคุณคิดว่าการตั้งค่าสถานะเฉพาะไม่มีประโยชน์ (หรือไม่ต้องการเลย) และทำไม

แก้ไข

ในการชี้แจงคำถามให้ทราบว่า-Wallมีคำเตือนพื้นฐานเพียงไม่กี่คำเท่านั้น
ที่จริงแล้วพวกเขามีการตั้งค่าสถานะการเตือนมากขึ้นซึ่งไม่ครอบคลุม-Wallดังนั้นคำถามและรายการที่ฉันให้


9
ฉันอยากจะบอกว่าสิ่งนี้น่าจะอยู่ใน Stack Overflow เนื่องจากเป็นคำถามเกี่ยวกับการใช้เครื่องมือ แต่เราจะเห็นว่าชุมชนมีการเปลี่ยนแปลงอย่างไร
อดัมเลียร์

ขอบคุณสำหรับความคิดเห็น:) ในทางฉันเห็นด้วยกับคุณและนั่นคือเหตุผลที่ฉันโพสต์ครั้งแรกใน StackOverflow (เพราะฉันไม่ใช่ผู้ใช้ปกติที่นี่อัปยศฉัน) ได้มุมมองมาก upvotes ฯลฯ ... แต่ไม่ใช่คำตอบเดียว ... และอย่างที่ผู้คนแนะนำให้ย้าย ... ดีมาดูกัน
:)

ฉันหวังว่าเราจะให้คำตอบที่ดีแก่คุณ โชคดี. :)
Adam Lear

สำหรับ C และ gcc -Wwrite-stringsทำให้คอมไพเลอร์ของภาษาคล้ายกันมาก แต่ไม่เหมือนกัน C ด้วยเหตุผลนั้นเพียงอย่างเดียวฉันไม่ได้ใช้ตัวเลือกนั้น อื่น ๆ ที่นอกเหนือจากที่คุณระบุผมใช้-pedantic -Wstrict-overflow=5 -Winline -Wundef -Wcast-qual -Wlogical-op -Wstrict-aliasing=2และสำหรับการเริ่มต้นที่ดีที่สุดที่เหมาะสม-Wno-missing-braces -Wno-missing-field-initializers struct whatever obj = {0};นอกจากนี้ฉันพบว่า-Wconversionให้ "สแปม" มากกว่าคำเตือนที่เป็นประโยชน์ :)
pmg

คำตอบ:


158

สำหรับบริบทฉันเป็นนักพัฒนาเสียงดังกราวทำงานที่ Google ที่ Google เราได้นำการวินิจฉัยของ Clang ออกมาให้กับนักพัฒนา C ++ ทุกคนและเราปฏิบัติต่อคำเตือนของ Clang ว่าเป็นข้อผิดพลาดเช่นกัน ในฐานะที่เป็นทั้งผู้พัฒนา Clang และหนึ่งในผู้ใช้ที่ใหญ่กว่าของ Clang Diagnostics ฉันจะพยายามทำให้กระจ่างในธงเหล่านี้และวิธีการใช้ โปรดทราบว่าทุกสิ่งที่ฉันอธิบายนั้นสามารถใช้กับเสียงดังกราวทั่วไปและไม่เฉพาะเจาะจงกับ C, C ++ หรือ Objective-C

TL; DR เวอร์ชัน: โปรดใช้-Wallและ-Werrorอย่างน้อยกับรหัสใหม่ใด ๆ ที่คุณกำลังพัฒนา เรา (ผู้พัฒนาคอมไพเลอร์) เพิ่มคำเตือนที่นี่ด้วยเหตุผลที่ดี: พวกเขาพบข้อบกพร่อง หากคุณพบคำเตือนที่จับข้อบกพร่องให้คุณเปิดเช่นกัน ลอง-Wextraหากลุ่มผู้สมัครที่ดีที่นี่ หากหนึ่งในนั้นคือมีเสียงดังมากเกินไปสำหรับคุณที่จะใช้กำไรยื่นข้อผิดพลาด หากคุณเขียนรหัสที่มีข้อผิดพลาด "ชัดเจน" แต่คอมไพเลอร์ไม่ได้เตือนเกี่ยวกับมันให้ยื่นข้อผิดพลาด

ตอนนี้สำหรับรุ่นยาว พื้นหลังแรกในการจัดกลุ่มธงเตือน คำเตือนใน Clang มี "กลุ่ม" จำนวนมาก (และในขอบเขตที่ จำกัด ใน GCC) บางส่วนที่เกี่ยวข้องกับการสนทนานี้:

  • โดยค่าเริ่มต้น: คำเตือนเหล่านี้จะเปิดอยู่เสมอเว้นแต่คุณจะปิดการใช้งานอย่างชัดเจน
  • -Wall: สิ่งเหล่านี้เป็นการเตือนว่าผู้พัฒนามีความมั่นใจสูงทั้งในด้านมูลค่าและอัตราการบวกลบที่ต่ำ
  • -Wextra: สิ่งเหล่านี้เป็นคำเตือนที่เชื่อว่ามีคุณค่าและเสียง (กล่าวคือพวกเขาไม่ได้บั๊ก) แต่พวกเขาอาจมีอัตราการบวกเท็จสูงหรือการคัดค้านทางปรัชญาที่พบบ่อย
  • -Weverything: นี่เป็นกลุ่มวิกลจริตที่เปิดใช้งานการ เตือนทุกครั้งใน Clang อย่าใช้สิ่งนี้กับรหัสของคุณ มันมีจุดมุ่งหมายอย่างเคร่งครัดสำหรับนักพัฒนาเสียงดังกราวหรือสำหรับการสำรวจสิ่งที่อยู่คำเตือน

มีเกณฑ์หลักสองข้อที่กล่าวถึงข้างต้นซึ่งเป็นแนวทางในการเตือนไปที่เสียงดังกังวานและให้ความกระจ่างแก่สิ่งเหล่านี้ ประการแรกคือ ค่าที่เป็นไปได้ของการเกิดขึ้นโดยเฉพาะของคำเตือน นี่คือประโยชน์ที่คาดว่าจะเกิดขึ้นกับผู้ใช้ (นักพัฒนา) เมื่อคำเตือนเริ่มทำงานและ ระบุปัญหาด้วยรหัสได้อย่างถูกต้อง

เกณฑ์ที่สองคือแนวคิดของรายงานที่ผิดพลาด เหล่านี้เป็นสถานการณ์ที่คำเตือนใช้รหัส แต่ปัญหาที่อาจเกิดขึ้นที่อ้างถึงนั้นไม่ได้เกิดขึ้นจริงเนื่องจากบริบทหรือข้อ จำกัด อื่น ๆ ของโปรแกรม รหัสเตือนเกี่ยวกับการทำงานจริงอย่างถูกต้อง สิ่งเหล่านี้เป็นสิ่งที่ไม่ดีโดยเฉพาะอย่างยิ่งเมื่อคำเตือนไม่เคยตั้งใจจะใช้รูปแบบรหัสนั้น แต่มันเป็นข้อบกพร่องในการใช้งานคำเตือนที่ทำให้เกิดไฟไหม้ที่นั่น

สำหรับคำเตือนแบบเสียงดังกังวานค่านั้นจำเป็นต้องอยู่ในรูปแบบของความถูกต้องไม่ใช่แบบแผนการลิ้มรสหรือแบบแผนการเข้ารหัส สิ่งนี้ จำกัด ชุดของการเตือนที่มีอยู่ซึ่งจะแยกการเตือนของการร้องขอที่ร้องขอเช่นคำเตือนเมื่อใดก็ตาม{}ที่ไม่ได้ใช้ s รอบ ๆ เนื้อความของifคำสั่ง เสียงดังกราวยังเป็นสิ่งที่ทนต่อความผิดพลาดได้เป็นอย่างมาก แตกต่างจากคอมไพเลอร์อื่น ๆ โดยส่วนใหญ่จะใช้แหล่งข้อมูลที่หลากหลายอย่างไม่น่าเชื่อในการตัดผลบวกปลอมรวมถึงการสะกดคำที่แน่นอนของสิ่งก่อสร้างการมีอยู่หรือไม่มีส่วนเสริม '()' การปลดเปลื้องหรือแม้แต่มาโครตัวประมวลผลล่วงหน้า!

ทีนี้ลองมาดูตัวอย่างคำเตือนในโลกแห่งความจริงจาก Clang แล้วดูว่าพวกมันถูกจัดหมวดหมู่อย่างไร ก่อนคำเตือนเริ่มต้น:

% nl x.cc
     1  class C { const int x; };

% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
      ^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
                    ^
1 warning generated.

ที่นี่ไม่จำเป็นต้องตั้งค่าสถานะเพื่อรับคำเตือนนี้ เหตุผลก็คือว่านี่เป็นรหัสที่ไม่ถูกต้องจริง ๆ ให้มูลค่าสูงเตือนและคำเตือนเพียงยิงบนรหัสที่เสียงดังกราวสามารถพิสูจน์ได้ตกอยู่ในถังนี้ทำให้มันเป็นศูนย์อัตราบวกเท็จ

% nl x2.cc
     1  int f(int x_) {
     2    int x = x;
     3    return x;
     4  }

% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
  int x = x;
      ~   ^
1 warning generated.

เสียงดังกราวต้องการ-Wallแฟล็กสำหรับคำเตือนนี้ เหตุผลก็คือมีรหัสที่ไม่สำคัญซึ่งมีการใช้รูปแบบโค้ดที่ดี (หรือไม่ดี) ที่เราได้รับคำเตือนเกี่ยวกับการสร้างมูลค่าที่ไม่ได้เตรียมไว้โดยเจตนา ในทางปรัชญาแล้วฉันไม่เห็นประเด็นใดในเรื่องนี้ แต่คนอื่น ๆ ไม่เห็นด้วยและความเป็นจริงของความแตกต่างในความเห็นนี้คือสิ่งที่ขับเคลื่อนการเตือนภายใต้ -Wallธง มันยังคงมีมูลค่าสูงมากและมีอัตราการบวกเป็นเท็จที่ต่ำมาก แต่สำหรับบางโค้ดมันเป็น non-starter

% nl x3.cc
     1  void g(int x);
     2  void f(int arr[], unsigned int size) {
     3    for (int i = 0; i < size; ++i)
     4      g(arr[i]);
     5  }

% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
  for (int i = 0; i < size; ++i)
                  ~ ^ ~~~~
1 warning generated.

คำเตือนนี้ต้องใช้-Wextraธง เหตุผลก็คือมี ฐานรหัสขนาดใหญ่มากซึ่งสัญญาณที่จับคู่ผิดในการเปรียบเทียบนั้นเป็นเรื่องธรรมดามาก ในขณะที่คำเตือนนี้พบข้อบกพร่องบางอย่างน่าจะเป็นของรหัสที่เป็นข้อผิดพลาดเมื่อผู้ใช้เขียนมันค่อนข้างต่ำโดยเฉลี่ย ผลที่ได้คืออัตราบวกเท็จที่สูงมาก แต่เมื่อมีข้อผิดพลาดในโปรแกรมเนื่องจากกฎโปรโมชั่นที่แปลกก็มักจะบอบบางมากทำให้คำเตือนนี้ เมื่อมันธงข้อผิดพลาดที่มีค่อนข้างสูงค่า เป็นผลให้เสียงดังกราวให้มันและเปิดเผยภายใต้ธง

โดยทั่วไปแล้วคำเตือนจะมีชีวิตอยู่ไม่นานนอก-Wextraธง เสียงดังกราวพยายามอย่างหนักที่จะไม่ใช้คำเตือนที่ไม่เห็นการใช้งานปกติและการทดสอบ คำเตือนเพิ่มเติมที่เปิดใช้โดย-Weverythingปกติแล้วคำเตือนภายใต้การพัฒนาที่ใช้งานอยู่หรือมีข้อบกพร่องที่ใช้งานอยู่ อาจจะได้รับการแก้ไขและวางไว้ภายใต้ธงที่เหมาะสมหรือควรลบออก

ตอนนี้เรามีความเข้าใจในการทำงานของสิ่งเหล่านี้กับ Clang แล้วลองกลับไปที่คำถามเดิม: คุณควรเปิดคำเตือนอะไรไว้สำหรับการพัฒนาของคุณ คำตอบคือน่าเสียดายที่มันขึ้นอยู่กับ ลองพิจารณาคำถามต่อไปนี้เพื่อช่วยพิจารณาว่าคำเตือนใดทำงานได้ดีที่สุดสำหรับสถานการณ์ของคุณ

  • คุณสามารถควบคุมรหัสทั้งหมดของคุณหรือเป็นบางส่วนภายนอกได้หรือไม่
  • เป้าหมายของคุณคืออะไร จับข้อบกพร่องหรือเขียนรหัสที่ดีกว่า
  • การยอมรับผิดพลาดของคุณคืออะไร คุณยินดีที่จะเขียนรหัสพิเศษเพื่อเงียบเตือนเป็นประจำหรือไม่

ก่อนอื่นถ้าคุณไม่ควบคุมรหัสอย่าพยายามเปิดคำเตือนเพิ่มเติมที่นั่น เตรียมพร้อมที่จะปิดบางอย่าง มีโค้ดที่ไม่ดีมากมายในโลกและคุณอาจไม่สามารถแก้ไขได้ทั้งหมด ไม่เป็นไร พยายามหาวิธีที่จะมุ่งเน้นความพยายามของคุณในรหัสที่คุณควบคุม

จากนั้นให้หาสิ่งที่คุณต้องการจากคำเตือนของคุณ สิ่งนี้แตกต่างกันไปสำหรับคนอื่น เสียงดังกราวจะพยายามเตือนโดยไม่มีตัวเลือกใด ๆ เกี่ยวกับข้อผิดพลาดร้ายแรงหรือรูปแบบรหัสที่เรามีมาก่อนหน้าประวัติศาสตร์ที่ยาวนานระบุอัตราข้อผิดพลาดที่สูงมาก เมื่อเปิดใช้งาน-Wallคุณจะได้รับชุดคำเตือนที่ก้าวร้าวมากขึ้นโดยมุ่งเน้นที่การจับข้อผิดพลาดที่พบบ่อยที่สุดซึ่งนักพัฒนาเสียงดังดังได้สังเกตเห็นในรหัส C ++ แต่ด้วยอัตราทั้ง บวกและลบควรมีอัตราที่ค่อนข้างต่ำ

สุดท้ายหากคุณยินดีที่จะเงียบ * เท็จบวก s * -Wextraทุกครั้งที่เลี้ยวไปสำหรับ ไฟล์บั๊กหากคุณสังเกตเห็นคำเตือนที่จับข้อผิดพลาดจริงจำนวนมาก แต่ที่มีข้อผิดพลาดที่โง่หรือไร้จุดหมาย เรากำลังทำงานอย่างต่อเนื่องเพื่อหาวิธีการที่จะนำมากขึ้นของตรรกะข้อผิดพลาดการค้นพบที่นำเสนอในการ-Wextraเข้าไปใน-Wallที่ที่เราสามารถหลีกเลี่ยงเท็จบวก

หลายคนจะพบว่าไม่มีตัวเลือกเหล่านี้ที่เหมาะสมสำหรับพวกเขา ที่ Google เราได้ปิดคำเตือน-Wallเนื่องจากรหัสที่มีอยู่จำนวนมากซึ่งละเมิดคำเตือน เราได้เปิดการเตือนบางอย่างอย่างชัดเจนแม้ว่าพวกเขาจะไม่ได้เปิดใช้งาน-Wallเพราะพวกเขามีค่าสูงเป็นพิเศษสำหรับเรา ระยะของคุณจะแตกต่างกัน แต่มีแนวโน้มที่จะแตกต่างกันไปในทำนองเดียวกัน -Wextraมันมักจะดีกว่าที่จะเปิดใช้งานคำเตือนที่สำคัญบางมากกว่าทั้งหมดของ

ฉันขอแนะนำให้ทุกคนเปิด-Wallใช้รหัสที่ไม่ได้รับมรดก สำหรับรหัสใหม่คำเตือนที่นี่มีค่าเกือบตลอดเวลาและทำให้การพัฒนาโค้ดดีขึ้น ตรงกันข้ามผมจะสนับสนุนให้ทุกคน ไม่ได้-Wextraเปิดใช้งานธงเกิน หากคุณพบว่าคำเตือนเสียงดังกราวที่-Wextra ไม่ได้รวมถึง แต่ที่พิสูจน์ที่ทุกคน-Wextraมีคุณค่าให้กับคุณเพียงแค่ยื่นข้อผิดพลาดและเราจะสามารถวางไว้ใต้ ไม่ว่าคุณจะเปิดใช้งานอย่างชัดเจนส่วนย่อยบางส่วนของคำเตือนในการจะขึ้นอยู่อย่างหนักในรหัสของคุณรูปแบบการเข้ารหัสของคุณและไม่ว่าจะรักษารายการที่ง่ายกว่าเครื่องประกอบทุกอย่างที่ค้นพบโดย-Wextra-Wextra

จากรายการคำเตือนของ OP (ซึ่งรวมทั้ง-Wallและ-Wextra) เฉพาะคำเตือนต่อไปนี้เท่านั้นที่ไม่ครอบคลุมโดยทั้งสองกลุ่ม (หรือเปิดตามค่าเริ่มต้น) กลุ่มแรกเน้นเหตุผลมากกว่าการพึ่งพาธงเตือนอย่างชัดเจนจะไม่ดี: ไม่มีของเหล่านี้จะได้ดำเนินการในเสียงดังกราว! พวกเขาได้รับการยอมรับในบรรทัดคำสั่งเฉพาะสำหรับความเข้ากันได้ของ GCC

  • -Wbad-function-cast
  • -Wdeclaration-after-statement
  • -Wmissing-format-attribute
  • -Wmissing-noreturn
  • -Wnested-externs
  • -Wnewline-eof
  • -Wold-style-definition
  • -Wredundant-decls
  • -Wsequence-point
  • -Wstrict-prototypes
  • -Wswitch-default

ที่เก็บข้อมูลชุดถัดไปของคำเตือนที่ไม่จำเป็นในรายการต้นฉบับคือคำเตือนที่ซ้ำซ้อนกับผู้อื่นในรายการนั้น:

  • -Wformat-nonliteral - ชุดย่อยของ -Wformat=2
  • -Wshorten-64-to-32 - ชุดย่อยของ -Wconversion
  • -Wsign-conversion - ชุดย่อยของ -Wconversion

นอกจากนี้ยังมีการเลือกคำเตือนที่แตกต่างกันอย่างมีนัยสำคัญ การจัดการกับตัวแปรภาษาถิ่นเหล่านี้แทนด้วยรหัส buggy หรือ non-buggy ด้วยข้อยกเว้น-Wwrite-stringsสิ่งเหล่านี้ล้วนเป็นคำเตือนสำหรับส่วนขยายภาษาที่จัดทำโดย Clang ว่าเสียงดังกราวเตือนเกี่ยวกับการใช้งานของพวกเขาขึ้นอยู่กับความชุกของส่วนขยาย เสียงดังกราวมีจุดประสงค์เพื่อความเข้ากันได้ของ GCC และในหลายกรณีมันช่วยลดความยุ่งยากในการใช้งานส่วนขยายภาษาโดยนัย -Wwrite-stringsตามความเห็นใน OP คือการตั้งค่าความเข้ากันได้จาก GCC ที่เปลี่ยนความหมายของโปรแกรม ฉันเสียใจอย่างสุดซึ้งกับธงนี้ แต่เราต้องสนับสนุนมันเนื่องจากมรดกที่มีอยู่ตอนนี้

  • -Wfour-char-constants
  • -Wpointer-arith
  • -Wwrite-strings

ตัวเลือกที่เหลือซึ่งเปิดใช้งานการเตือนที่น่าสนใจจริง ๆ คือ:

  • -Wcast-align
  • -Wconversion
  • -Wfloat-equal
  • -Wformat=2
  • -Wimplicit-atomic-properties
  • -Wmissing-declarations
  • -Wmissing-prototypes
  • -Woverlength-strings
  • -Wshadow
  • -Wstrict-selector-match
  • -Wundeclared-selector
  • -Wunreachable-code

เหตุผลที่สิ่งเหล่านี้ไม่ได้อยู่ใน-Wallหรือ-Wextraไม่ชัดเจนเสมอไป สำหรับหลาย ๆ คนเหล่านี้พวกเขาจะจริงตามคำเตือน GCC ( -Wconversion, -Wshadowฯลฯ ) และเป็นเสียงดังกราวดังกล่าวพยายามที่จะเลียนแบบพฤติกรรมของ GCC เราค่อยๆแบ่งสิ่งเหล่านี้ออกเป็นคำเตือนที่เป็นประโยชน์และมีประโยชน์มากขึ้น สิ่งเหล่านั้นมีโอกาสสูงที่จะทำให้มันเป็นหนึ่งในกลุ่มเตือนระดับบนสุด ที่กล่าวว่าจะรับในหนึ่งเตือน-Wconversionเป็นดังนั้นในวงกว้างว่ามันมีแนวโน้มที่จะยังคงอยู่ในตัวเอง "ระดับบน" หมวดหมู่ของมันในอนาคตอันใกล้ คำเตือนอื่น ๆ ที่ GCC มี แต่ที่มีค่าต่ำและอัตราการบวกเท็จที่สูงอาจถูกผลักไสให้ไปที่ไม่มีที่ดินของมนุษย์ที่คล้ายกัน

เหตุผลอื่น ๆ ที่ว่าทำไมสิ่งเหล่านี้ไม่ได้อยู่ในหนึ่งในถังที่ใหญ่กว่านั้นรวมถึงข้อบกพร่องอย่างง่ายปัญหาเชิงบวกที่ผิดพลาดที่สำคัญมากและคำเตือนระหว่างการพัฒนา ฉันจะดูข้อผิดพลาดในการยื่นสำหรับสิ่งที่ฉันสามารถระบุได้ ในที่สุดพวกเขาทั้งหมดควรโยกย้ายไปที่ธงถังขนาดใหญ่ที่เหมาะสมหรือถูกลบออกจากเสียงดังกราว

ฉันหวังว่าสิ่งนี้จะอธิบายสถานการณ์เตือนด้วย Clang และให้ข้อมูลเชิงลึกแก่ผู้ที่พยายามเลือกชุดคำเตือนสำหรับการใช้งานหรือการใช้งานของ บริษัท


8
คำตอบที่โดดเด่น! ขอบคุณมาก. ฉันจะต้องอ่านใหม่อีกสองสามครั้ง แต่ฉันจะกลับมาเร็ว ๆ นี้พร้อมความคิดเห็น ขอบคุณอีกครั้ง!
Macmade

1
@Chandler Carruth: คำตอบยอดเยี่ยม! แต่คุณสามารถอัปเดตได้ไหมถ้ามีอะไรเปลี่ยนแปลง? ฉันใช้คำเตือนทั้งหมดของคุณในรายการสุดท้ายของคุณ แต่อาจมีบางคนถูกย้ายไปยัง Wextra แล้วหรือไม่
gartenriese

นี่คือโพสต์ที่ยอดเยี่ยม แต่การค้นหาคำเตือนใหม่คือฉันพบว่าเป็นประโยชน์อย่างยิ่งสำหรับธงดังนั้นฉันจึงผิดหวังที่คุณดูเหมือนจะถูกลบไปยังกลุ่ม "ทุกอย่าง" แม้ว่าจะยอมรับว่ามันมีประโยชน์สำหรับการสำรวจประเภทนี้
Kyle Strand

@Chandler Carruth: ฉันเห็นด้วยกับเหตุผลเบื้องหลังคำเตือนเกี่ยวกับรหัส "ไม่ถูกต้องจริงๆ" เป็นเพียงการไม่มี-Wnoการปิดwarn_no_constructor_for_refconst ทำให้ PITA ใช้ Boost.ConceptCheck และเหมือนกัน: github.com/boostorg/concept_check/blob/
......

2

ฉันไม่ได้ใช้เสียงดังกราว แต่ฉันหวังว่าคุณจะไม่สนใจความเห็นของฉันเช่นกัน ฉันยังไปพร้อมกับระดับการเตือนสูงสุด (ฉันคิดว่านั่นคือสิ่งที่ - หมายถึงทั้งหมด) และด้วยการปฏิบัติต่อคำเตือนว่าเป็นข้อผิดพลาด ที่จริงแล้วฉันค่อนข้างรำคาญกับความจริงที่ว่าคำเตือนที่มีประโยชน์บางอย่างไม่ได้รับการเผยแพร่โดยคอมไพเลอร์ C # และหนึ่งต้องเรียกใช้เครื่องมือวิเคราะห์รหัสพิเศษเพื่อดูพวกเขา ฉันชอบคำเตือนเพราะพวกเขาช่วยฉันตรวจจับข้อผิดพลาดเล็ก ๆ น้อย ๆ ในรหัสของฉัน ฉันชอบพวกเขามากเมื่อมีการออกคำเตือนสำหรับรหัสที่ฉันรู้ว่าถูกต้องฉันจะสร้างส่วนของรหัสใหม่เพื่อไม่ให้มีการออกคำเตือนแทนที่จะปิดใช้งานการเตือนหรือ - สิบเอ็ด แย่กว่า - อนุญาตให้มันปรากฏขึ้นและไม่สนใจมัน ฉันคิดว่าคำเตือนยอดเยี่ยม


1
ขอบคุณสำหรับคำตอบ. น่าเสียดายที่-Wallให้คำเตือนพื้นฐานเท่านั้น ธงคำเตือนที่มีอยู่จำนวนมากไม่ได้รับการคุ้มครอง-Wallดังนั้นรายการในคำถามของฉัน
Macmade

0

ฉันมักจะไปกับการตั้งค่าเริ่มต้นของ Xcode สำหรับโครงการใหม่ มันให้ความสมดุลที่ดีของการช่วยเหลือและน่ารำคาญ รายการคำเตือนเฉพาะเจาะจงและตัวเลือกคอมไพเลอร์อื่น ๆ จะขึ้นอยู่กับความชอบส่วนตัวหรือข้อกำหนดของโครงการเป็นหลักดังนั้นฉันไม่คิดว่าจะมีมูลค่ามากในการพยายามดูรายการของคุณและโต้แย้งหรือคัดค้านคำเตือนเฉพาะ ถ้ามันเหมาะกับคุณมาก หากคุณพบว่าคุณได้ทำข้อผิดพลาดบางอย่างที่คอมไพเลอร์ควรตรวจจับได้และคุณต้องการความช่วยเหลือในเรื่องนี้ในอนาคตให้มองหาตัวเลือกคอมไพเลอร์เพื่อเตือนเกี่ยวกับสิ่งนั้นและเปิดใช้งาน

สิ่งหนึ่งที่ผู้ให้การสนับสนุนโปรแกรมเมอร์จำนวนมากกำลังเปิดตัวเลือก "Treat Warnings as Errors" (-Werror) เพื่อป้องกันไม่ให้บิลด์จากการทำสำเร็จหากมีคำเตือนใด ๆ


ขอบคุณสำหรับคำตอบ! -Werrorผมเห็นด้วยกับ ที่จริงแล้วเป็นฉันใช้เสียงดังกราวผมตั้งค่าทั้งหมดของคำเตือนเหล่านี้โดยใช้ pragmas (#pragma เสียงดังกราววินิจฉัย) และพวกเขาจะถูกตั้งข้อผิดพลาดร้ายแรงดังนั้นนี้เป็นเช่นเดียวกับ-Werror:)
Macmade

0

ฉันคิดว่าหลักฐานที่ดีที่สุดที่ผู้คนสนใจเกี่ยวกับคำเตือนคือความจริงที่ว่าพวกเขามีอยู่จริงและถูกนำมาใช้อย่างกว้างขวาง ฉันเห็นด้วยอย่างยิ่งว่ายิ่งมีข้อผิดพลาดเกิดขึ้นระหว่างการรวบรวม หากนี่ไม่ใช่ความเชื่อที่ยึดถือกันอย่างแพร่หลายทุกคนจะใช้ภาษาที่มีการพิมพ์แบบไดนามิกที่อ่อนแอเนื่องจากคอมไพเลอร์หรือล่ามของพวกเขาจะช่วยให้คุณมีเวลามากขึ้น ในทางตรงกันข้ามแม้ในภาษาสคริปต์การใช้งานstrictธงเป็นที่นิยม ในภาษาที่มีการพิมพ์อย่างรุนแรงไม่เพียง แต่คนใช้-Wall -Werrorบ่อย แต่พวกเขามักจะพบคำเตือนที่มีค่าที่พวกเขาต้องการมากยิ่งขึ้นดังนั้นพวกเขาจึงจ่ายเงินสำหรับเครื่องมือวิเคราะห์แบบคงที่เช่นCoverityซึ่งมีวัตถุประสงค์เพียงอย่างเดียว

ไม่ได้หมายความว่าไม่มีผู้ว่า นักพัฒนาซอฟต์แวร์หลายคนเห็นคำเตือนว่าทำงานกับพวกเขาในระยะสั้นแทนที่จะทำงานให้พวกเขาในระยะยาวและไม่พยายามแก้ไขปัญหาพื้นฐาน ดังนั้นคุณจะเห็นโค้ดที่น่ารักแบบนี้ฉันพบเมื่อวานนี้:

node = node; // Shut up compiler warning

ขอบคุณสำหรับคำตอบ. ปัญหาคือฉันมักจะเห็นคนที่ทำงานโดยไม่-Werrorได้และจริง ๆ แล้วไม่สนใจคำเตือนที่ออกโดยคอมไพเลอร์ -Wallหรือถ้าพวกเขาทำพวกเขาก็มักจะยึดติดอยู่กับ ธงส่วนใหญ่ที่ฉันให้ไว้ในคำถามของฉันยังไม่ครอบคลุม-Wallและฉันคิดว่าพวกเขาเองก็มีความสำคัญเช่นกัน ดังนั้นฉันแค่หวาดระแวง? ; )
Macmade

0

โดยทั่วไปแล้วฉันเอนไปทาง -Wall และเชื่อในสิ่งนั้นอย่างแน่นอนรวมถึง -Werror โมดูลไม่ควรมีคำเตือนที่คาดหวัง ในที่สุดคุณจะได้รับคำเตือนอีกครั้งและคิดถึงมัน และนั่นจะเป็นปัญหาที่เกิดขึ้นจริง

นอกจากนี้ยังขึ้นอยู่กับว่าคุณกำลังเพิ่ม "-Wall -Werror" ในโครงการใหม่หรือเก่า หากเป็นเรื่องใหม่ลองไปหาและเรียกร้องความสมบูรณ์แบบไม่เช่นนั้นคุณอาจจะต้องทำการแก้ไขและทดสอบเป็นวันหรือหลายสัปดาห์ ฉันเพิ่งทำสิ่งนี้ในโครงการขนาดเล็กที่เก่ากว่าและฉันใช้เวลาสองหรือสามวันในการลบคำเตือน ฉันคิดว่ารหัสนี้สะอาดขึ้นแล้ว

ลองลองดูอีกครั้ง

มีตัณหา


1
หากคุณเป็นห่วงเท่านั้น-Wallและ-Werrorฉันคิดว่าคุณควรอ่านคำถามอีกครั้ง -Wallจำนวนมากของธงเตือนจะไม่ครอบคลุมโดย ขอบคุณสำหรับคำตอบ
Macmade
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.