ฉันได้ตรวจสอบและพบชุดรวมขั้นต่ำที่ควรได้รับคำเตือนในระดับสูงสุด จากนั้นฉันก็ลบชุดคำเตือนออกจากรายการนั้นซึ่งฉันรู้สึกว่าไม่ได้บ่งชี้ว่ามีสิ่งเลวร้ายเกิดขึ้นจริงหรืออย่างอื่นมีผลบวกเท็จมากเกินไปที่จะใช้ในงานสร้างจริง ฉันแสดงความคิดเห็นว่าเหตุใดแต่ละรายการที่ฉันยกเว้นจึงถูกยกเว้น นี่คือคำเตือนที่แนะนำชุดสุดท้ายของฉัน:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
คำเตือนที่น่าสงสัยที่มีอยู่:
ฉันรวมไว้-Wno-unused
เพราะฉันมักจะมีตัวแปรที่ฉันรู้ว่าจะใช้ในภายหลัง แต่ยังไม่มีฟังก์ชันที่เขียนไว้ การลบคำเตือนเกี่ยวกับเรื่องนี้ช่วยให้ฉันสามารถเขียนในรูปแบบที่ฉันต้องการได้ในบางครั้งการเลื่อนการใช้งานสิ่งต่างๆ จะมีประโยชน์ในการปิดทุกครั้งเพื่อให้แน่ใจว่าไม่มีอะไรเล็ดรอดผ่านรอยแตก
-Wdisabled-optimization
ดูเหมือนว่าเป็นการตั้งค่าความชอบของผู้ใช้ที่แข็งแกร่ง ฉันเพิ่งเพิ่มสิ่งนี้ลงในงานสร้างของฉัน (สำหรับงานสร้างที่ได้รับการปรับให้เหมาะสมด้วยเหตุผลที่ชัดเจนเท่านั้น) และมันไม่ได้เปิดอะไรเลยดูเหมือนจะไม่ใช่คำเตือนโดยเฉพาะอย่างยิ่งสำหรับวิธีที่ฉันเขียนโค้ด ฉันรวมไว้ (แม้ว่ารหัสที่เรียกคำเตือนนี้ไม่จำเป็นต้องผิด) เพราะฉันเชื่อในการทำงานกับเครื่องมือของฉันแทนที่จะต่อต้านพวกเขา หาก gcc บอกฉันว่ามันไม่สามารถปรับแต่งโค้ดให้เหมาะสมกับวิธีที่ฉันเขียนได้ฉันควรดูที่การเขียนใหม่ ฉันสงสัยว่ารหัสที่เรียกคำเตือนนี้อาจได้รับประโยชน์จากการเป็นโมดูลาร์มากขึ้นโดยไม่คำนึงถึงแม้ว่ารหัสจะไม่ผิดในทางเทคนิค (อาจ) ในทางโวหารก็เป็นไปได้
-Wfloat-equal
เตือนสำหรับการเปรียบเทียบความเท่าเทียมกันอย่างปลอดภัย (โดยเฉพาะอย่างยิ่งการเปรียบเทียบกับค่าที่ไม่ได้คำนวณเป็น -1) ตัวอย่างในโค้ดของฉันที่ฉันใช้นี่คือฉันมีเวกเตอร์ลอย ฉันอ่านเวกเตอร์นี้และมีองค์ประกอบบางอย่างที่ฉันยังประเมินไม่ได้ว่าควรจะเป็นอย่างไรดังนั้นฉันจึงตั้งค่าเป็น -1.0f (เนื่องจากปัญหาของฉันใช้ตัวเลขบวกเท่านั้น -1 จึงอยู่นอกโดเมน) หลังจากนั้นฉันจะผ่านและอัปเดตค่า -1.0f มันไม่ง่ายที่จะยืมตัวเองไปใช้วิธีการทำงานอื่น ๆ ฉันสงสัยว่าคนส่วนใหญ่ไม่มีปัญหานี้และการเปรียบเทียบจำนวนที่แน่นอนในทศนิยมอาจเป็นข้อผิดพลาดดังนั้นฉันจึงรวมไว้ในรายการเริ่มต้น
-Wold-style-cast
มีผลบวกลวงจำนวนมากในรหัสไลบรารีที่ฉันใช้ โดยเฉพาะอย่างยิ่งฟังก์ชั่นตระกูล htonl ที่ใช้ในระบบเครือข่ายรวมถึงการใช้งานการเข้ารหัส Rijndael (AES) ที่ฉันใช้อยู่มีแคสต์แบบเก่าที่เตือนฉันเกี่ยวกับ ฉันตั้งใจจะแทนที่ทั้งสองอย่างนี้ แต่ฉันไม่แน่ใจว่ามีอะไรอีกในรหัสของฉันที่จะบ่น ผู้ใช้ส่วนใหญ่น่าจะเปิดไว้โดยค่าเริ่มต้น
-Wsign-conversion
เป็นคนที่ยาก (และแทบไม่ได้ทำรายการ) การเปิดใช้งานในรหัสของฉันทำให้เกิดคำเตือนจำนวนมาก (100+) เกือบทั้งหมดเป็นผู้บริสุทธิ์ อย่างไรก็ตามฉันใช้ความระมัดระวังในการใช้จำนวนเต็มที่ลงนามในทุกที่ที่ฉันไม่แน่ใจแม้ว่าสำหรับโดเมนปัญหาเฉพาะของฉันฉันมักจะได้รับประสิทธิภาพเพิ่มขึ้นเล็กน้อยโดยใช้ค่าที่ไม่ได้ลงชื่อเนื่องจากการหารจำนวนเต็มจำนวนมากที่ฉันทำ ฉันเสียสละประสิทธิภาพนี้เพราะฉันกังวลเกี่ยวกับการส่งเสริมจำนวนเต็มที่ลงนามโดยไม่ได้ตั้งใจให้เป็นจำนวนเต็มที่ไม่ได้ลงชื่อแล้วหาร (ซึ่งไม่ปลอดภัยซึ่งแตกต่างจากการบวกการลบและการคูณ) การเปิดคำเตือนนี้ทำให้ฉันสามารถเปลี่ยนตัวแปรส่วนใหญ่เป็นประเภทที่ไม่ได้ลงชื่อได้อย่างปลอดภัยและเพิ่มการร่ายในที่อื่น ๆ ขณะนี้ใช้งานยากเล็กน้อยเนื่องจากคำเตือนไม่ฉลาดเท่าไหร่ ตัวอย่างเช่นถ้าคุณทำunsigned short + (integral
constant expression)
ผลลัพธ์นั้นได้รับการเลื่อนขั้นเป็น int โดยปริยาย จากนั้นจะเตือนเกี่ยวกับปัญหาสัญญาณที่อาจเกิดขึ้นหากคุณกำหนดค่านั้นให้
unsigned
หรือunsigned short
แม้ว่าจะปลอดภัยก็ตาม นี่เป็นคำเตือนที่เป็นทางเลือกมากที่สุดสำหรับผู้ใช้เกือบทั้งหมด
-Wsign-promo
: ดู-Wsign-conversion
.
-Wswitch-default
ดูเหมือนไม่มีจุดหมาย (คุณไม่ต้องการกรณีเริ่มต้นเสมอไปหากคุณระบุความเป็นไปได้ทั้งหมดอย่างชัดเจน) อย่างไรก็ตามการเปิดคำเตือนนี้สามารถบังคับใช้บางสิ่งที่น่าจะเป็นความคิดที่ดี สำหรับกรณีที่คุณต้องการละเว้นทุกอย่างอย่างชัดเจนยกเว้นความเป็นไปได้ที่ระบุไว้ (แต่ตัวเลขอื่นเป็นไปได้) ให้ใส่default: break;
เพื่อให้ชัดเจน หากคุณระบุความเป็นไปได้ทั้งหมดอย่างชัดเจนการเปิดคำเตือนนี้จะช่วยให้แน่ใจว่าคุณใส่บางอย่างเช่นยืนยัน (เท็จ) เพื่อให้แน่ใจว่าคุณได้ครอบคลุมตัวเลือกที่เป็นไปได้ทั้งหมดแล้ว ช่วยให้คุณเข้าใจได้อย่างชัดเจนว่าโดเมนของปัญหาของคุณคืออะไรและบังคับใช้โดยทางโปรแกรม อย่างไรก็ตามคุณจะต้องระมัดระวังในการยืนยัน (เท็จ) ทุกที่ จะดีกว่าการไม่ทำอะไรเลยกับกรณีเริ่มต้น แต่ตามปกติเมื่อยืนยันแล้วจะใช้ไม่ได้ในรุ่นรุ่น กล่าวอีกนัยหนึ่งคุณไม่สามารถวางใจได้ในการตรวจสอบหมายเลขที่คุณได้รับเช่นการเชื่อมต่อเครือข่ายหรือฐานข้อมูลที่คุณไม่สามารถควบคุมได้ทั้งหมด ข้อยกเว้นหรือการกลับมาก่อนเวลาเป็นวิธีที่ดีที่สุดในการจัดการ (แต่ยังต้องให้คุณมีกรณีเริ่มต้น!)
-Werror
เป็นสิ่งที่สำคัญสำหรับฉัน เมื่อรวบรวมโค้ดจำนวนมากในบิวด์แบบมัลติเธรดที่มีหลายเป้าหมายคำเตือนจะหลุดมือได้ง่าย การเปลี่ยนคำเตือนให้เป็นข้อผิดพลาดทำให้ฉันสังเกตเห็นได้
จากนั้นมีชุดคำเตือนที่ไม่รวมอยู่ในรายการด้านบนเนื่องจากฉันไม่พบว่ามีประโยชน์ นี่คือคำเตือนและความคิดเห็นของฉันเกี่ยวกับสาเหตุที่ฉันไม่รวมไว้ในรายการเริ่มต้น:
คำเตือนที่ไม่มี:
-Wabi
ไม่จำเป็นเพราะฉันไม่ได้รวมไบนารีจากคอมไพเลอร์อื่น ฉันพยายามรวบรวมมันแล้ว แต่มันก็ไม่เกิดขึ้นดังนั้นมันจึงดูเหมือนไม่จำเป็นอย่างยิ่ง
-Waggregate-return
ไม่ใช่สิ่งที่ฉันถือว่าเป็นข้อผิดพลาด ตัวอย่างเช่นจะทริกเกอร์เมื่อใช้ range-based for loop บนเวกเตอร์ของคลาส การเพิ่มประสิทธิภาพค่าตอบแทนควรดูแลผลกระทบเชิงลบของสิ่งนี้
-Wconversion
ทริกเกอร์รหัสนี้: short n = 0; n += 2;
การแปลงโดยนัยเป็น int ทำให้เกิดคำเตือนเมื่อแปลงกลับเป็นประเภทเป้าหมายแล้ว
-Weffc++
รวมคำเตือนหากสมาชิกข้อมูลทั้งหมดไม่ได้เตรียมใช้งานในรายการตัวเริ่มต้น ฉันตั้งใจที่จะไม่ทำเช่นนี้ในหลาย ๆ กรณีดังนั้นชุดคำเตือนจึงรกเกินกว่าที่จะเป็นประโยชน์ การเปิดใช้งานเป็นระยะ ๆ และสแกนหาคำเตือนอื่น ๆ จะเป็นประโยชน์ (เช่นตัวทำลายที่ไม่ใช่เสมือนของคลาสพื้นฐาน) สิ่งนี้จะมีประโยชน์มากกว่าในการรวบรวมคำเตือน (เช่น-Wall
) แทนที่จะเป็นคำเตือนเดียว
-Winline
ไม่อยู่เนื่องจากฉันไม่ได้ใช้คำหลักแบบอินไลน์เพื่อวัตถุประสงค์ในการเพิ่มประสิทธิภาพเพียงเพื่อกำหนดฟังก์ชันแบบอินไลน์ในส่วนหัว ฉันไม่สนใจว่าเครื่องมือเพิ่มประสิทธิภาพจะแทรกตัวอยู่หรือไม่ คำเตือนนี้ยังบ่นหากไม่สามารถแทรกฟังก์ชันที่ประกาศไว้ในเนื้อหาคลาสได้ (เช่นตัวทำลายเสมือนที่ว่างเปล่า)
-Winvalid-pch
หายไปเพราะฉันไม่ได้ใช้ส่วนหัวที่คอมไพล์ไว้ล่วงหน้า
-Wmissing-format-attribute
ไม่ได้ใช้เพราะฉันไม่ได้ใช้ส่วนขยาย gnu เหมือนกัน-Wsuggest-attribute
และอื่น ๆ อีกมากมาย
อาจเป็นที่น่าสังเกตสำหรับการไม่มีอยู่-Wno-long-long
ซึ่งฉันไม่จำเป็นต้องมี ฉันรวบรวมด้วย-std=c++0x
( -std=c++11
ใน GCC 4.7) ซึ่งรวมถึงlong long
ประเภทจำนวนเต็ม ผู้ที่ติดอยู่ใน C ++ 98 / C ++ 03 อาจพิจารณาเพิ่มการยกเว้นนั้นจากรายการคำเตือน
-Wnormalized=nfc
เป็นตัวเลือกเริ่มต้นอยู่แล้วและดูเหมือนจะดีที่สุด
-Wpadded
จะเปิดเป็นครั้งคราวเพื่อปรับเลย์เอาต์ของชั้นเรียนให้เหมาะสมที่สุด แต่ก็ไม่ได้เปิดไว้เนื่องจากบางชั้นเรียนมีองค์ประกอบไม่เพียงพอที่จะลบช่องว่างในตอนท้าย ตามทฤษฎีแล้วฉันจะได้รับตัวแปรพิเศษบางตัวสำหรับ 'ฟรี' แต่ก็ไม่คุ้มค่ากับความพยายามเพิ่มเติมในการดูแลรักษา (หากขนาดชั้นเรียนของฉันเปลี่ยนไปการลบตัวแปรฟรีก่อนหน้านี้นั้นไม่ใช่เรื่องง่าย)
-Wstack-protector
ไม่ได้ใช้เพราะฉันไม่ได้ใช้ -fstack-protector
-Wstrict-aliasing=3
เปิดอยู่-Wall
และแม่นยำที่สุด แต่ดูเหมือนว่าระดับ 1 และ 2 จะให้คำเตือนมากกว่า ตามทฤษฎีแล้วระดับที่ต่ำกว่าคือคำเตือนที่ 'แรงกว่า' แต่ก็มีค่าใช้จ่ายของผลบวกที่ผิดพลาดมากกว่า รหัสทดสอบของฉันเองรวบรวมอย่างหมดจดภายใต้ทั้ง 3 ระดับ
-Wswitch-enum
ไม่ใช่พฤติกรรมที่ฉันต้องการ ฉันไม่ต้องการจัดการทุกคำสั่งสวิตช์อย่างชัดเจน มันจะมีประโยชน์ถ้าภาษามีกลไกบางอย่างในการเปิดใช้งานสิ่งนี้ในคำสั่ง switch ที่ระบุ (เพื่อให้แน่ใจว่าการเปลี่ยนแปลงในอนาคตของ enum จะได้รับการจัดการทุกที่ที่จำเป็นต้องเป็น) แต่มันเกินความจำเป็นสำหรับการตั้งค่า "ทั้งหมดหรือไม่มีเลย"
-Wunsafe-loop-optimizations
ทำให้เกิดคำเตือนที่หลอกลวงมากเกินไป อาจเป็นประโยชน์ในการใช้สิ่งนี้เป็นระยะและตรวจสอบผลลัพธ์ด้วยตนเอง ตัวอย่างเช่นมันสร้างคำเตือนนี้ในโค้ดของฉันเมื่อฉันวนซ้ำองค์ประกอบทั้งหมดในเวกเตอร์เพื่อใช้ชุดของฟังก์ชันกับพวกเขา (โดยใช้ range-based สำหรับการวนซ้ำ) นอกจากนี้ยังเป็นการเตือนสำหรับตัวสร้างของอาร์เรย์ const ของ const std :: string (โดยที่นี่ไม่ใช่การวนซ้ำในรหัสผู้ใช้)
-Wzero-as-null-pointer-constant
และ-Wuseless-cast
เป็นคำเตือนเฉพาะ GCC-4.7 ซึ่งฉันจะเพิ่มเมื่อเปลี่ยนเป็น GCC 4.7
ฉันได้ยื่นรายงานข้อบกพร่อง / คำขอการปรับปรุงบางส่วนที่ gcc อันเป็นผลมาจากการวิจัยบางส่วนดังนั้นหวังว่าในที่สุดฉันจะสามารถเพิ่มคำเตือนจากรายการ "ไม่รวม" ไปยังรายการ "รวม" ได้ . รายการนี้มีคำเตือนทั้งหมดที่กล่าวถึงในชุดข้อความนี้ (และฉันคิดว่ามีอะไรเพิ่มเติมอีกเล็กน้อย) คำเตือนหลายคำที่ไม่ได้กล่าวถึงอย่างชัดเจนในโพสต์นี้รวมอยู่ในคำเตือนอื่นที่ฉันพูดถึง หากใครสังเกตเห็นคำเตือนใด ๆ ที่ไม่รวมอยู่ในโพสต์นี้โปรดแจ้งให้เราทราบ
แก้ไข:ดูเหมือนว่าฉันพลาดหลายอย่าง (ซึ่งตอนนี้ฉันได้เพิ่มเข้าไปแล้ว) มีหน้าที่สองที่http://gcc.gnu.orgซึ่งซ่อนไว้ค่อนข้างดี ตัวเลือกคำเตือนทั่วไปและตัวเลือกC ++ (เลื่อนลงไปด้านล่างเพื่อดูคำเตือน)
-Wall
) เป็น-Wbloody_everything
ธง :-)