ฉันมักจะได้ยินว่าเมื่อรวบรวมโปรแกรม C และ C ++ ฉันควร "เปิดใช้งานคำเตือนคอมไพเลอร์" เสมอ ทำไมถึงจำเป็น ฉันจะทำอย่างไร
บางครั้งฉันก็ได้ยินว่าฉันควร "ถือว่าคำเตือนเป็นข้อผิดพลาด" ฉันควร? ฉันจะทำอย่างไร
ฉันมักจะได้ยินว่าเมื่อรวบรวมโปรแกรม C และ C ++ ฉันควร "เปิดใช้งานคำเตือนคอมไพเลอร์" เสมอ ทำไมถึงจำเป็น ฉันจะทำอย่างไร
บางครั้งฉันก็ได้ยินว่าฉันควร "ถือว่าคำเตือนเป็นข้อผิดพลาด" ฉันควร? ฉันจะทำอย่างไร
คำตอบ:
คอมไพเลอร์ C และ C ++ ไม่ดีอย่างมากที่รายงานข้อผิดพลาดทั่วไปของโปรแกรมเมอร์โดยค่าเริ่มต้นเช่น:
return
ค่าจากฟังก์ชั่นprintf
และscanf
ตระกูลที่ไม่ตรงกับสตริงรูปแบบสิ่งเหล่านี้สามารถตรวจพบและรายงานโดยปกติแล้วจะไม่ได้รับการตั้งค่า คุณสมบัตินี้ต้องได้รับการร้องขออย่างชัดเจนผ่านตัวเลือกคอมไพเลอร์
ขึ้นอยู่กับคอมไพเลอร์ของคุณ
ไมโครซอฟท์ C และ C ++ คอมไพเลอร์สวิทช์เข้าใจชอบ/W1
, /W2
, /W3
, และ/W4
ใช้เวลาอย่างน้อย/Wall
และอาจปล่อยคำเตือนปลอมสำหรับไฟล์ส่วนหัวของระบบ แต่ถ้าโครงการของคุณคอมไพล์อย่างสมบูรณ์ด้วยหนึ่งในตัวเลือกเหล่านี้ไปได้เลย ตัวเลือกเหล่านี้ไม่สามารถใช้ร่วมกันได้/W3
/W4
/Wall
ส่วนใหญ่คอมไพเลอร์อื่น ๆ เข้าใจตัวเลือกเช่น-Wall
, และ-Wpedantic
เป็นสิ่งจำเป็นและส่วนที่เหลือทั้งหมดได้รับการแนะนำ (โปรดทราบว่าแม้จะมีชื่อแต่ก็สามารถเปิดใช้งานการเตือนที่สำคัญที่สุดเท่านั้นไม่ใช่ทั้งหมด ) ตัวเลือกเหล่านี้สามารถใช้แยกกันหรือรวมเข้าด้วยกัน-Wextra
-Wall
-Wall
IDE ของคุณอาจมีวิธีการเปิดใช้งานสิ่งเหล่านี้จากส่วนต่อประสานผู้ใช้
คำเตือนคอมไพเลอร์ส่งสัญญาณว่าอาจมีปัญหาร้ายแรงในรหัสของคุณ ปัญหาที่กล่าวข้างต้นมักเป็นอันตรายถึงชีวิต คนอื่นอาจจะใช่หรือไม่ใช่ แต่คุณต้องการให้การรวบรวมล้มเหลวแม้ว่ามันจะเป็นสัญญาณเตือนที่ผิดพลาดก็ตาม ตรวจสอบคำเตือนแต่ละรายการค้นหาสาเหตุที่แท้จริงและแก้ไข ในกรณีที่มีการเตือนที่ผิดพลาดให้หลีกเลี่ยง - นั่นคือใช้คุณสมบัติภาษาอื่นหรือสร้างเพื่อไม่ให้มีการเตือนอีกต่อไป หากนี่พิสูจน์ได้ว่าเป็นเรื่องยากมากให้ปิดใช้งานคำเตือนนั้นเป็นราย ๆ ไป
คุณไม่ต้องการเพียงแค่ปล่อยให้คำเตือนเป็นคำเตือนแม้ว่าพวกเขาทั้งหมดจะเป็นสัญญาณเตือนที่ผิดพลาด มันอาจจะโอเคสำหรับโครงการขนาดเล็กมากซึ่งจำนวนคำเตือนทั้งหมดที่ปล่อยออกมาน้อยกว่า 7 มีอะไรเพิ่มเติมและมันง่ายสำหรับการเตือนใหม่ที่จะหลงทางในเหตุการณ์ที่คุ้นเคยเก่า ๆ ไม่อนุญาต เพียงทำให้โครงการทั้งหมดของคุณรวบรวมได้อย่างหมดจด
หมายเหตุสิ่งนี้ใช้กับการพัฒนาโปรแกรม หากคุณกำลังปล่อยโปรเจ็กต์ของคุณสู่โลกในรูปแบบของแหล่งที่มามันอาจเป็นความคิดที่ดีที่จะไม่จัดหา-Werror
หรือเทียบเท่าในสคริปต์สร้างของคุณที่วางจำหน่าย ผู้คนอาจพยายามสร้างโครงการของคุณด้วยคอมไพเลอร์เวอร์ชันอื่นหรือคอมไพเลอร์ที่แตกต่างกันโดยสิ้นเชิงซึ่งอาจเปิดใช้คำเตือนชุดอื่น คุณอาจต้องการสร้างงานให้สำเร็จ ยังคงเป็นความคิดที่ดีที่จะเปิดใช้งานคำเตือนเพื่อให้ผู้ที่เห็นข้อความเตือนสามารถส่งรายงานข้อผิดพลาดหรือแพตช์ให้คุณได้
สิ่งนี้จะทำอีกครั้งด้วยสวิตช์คอมไพเลอร์ /WX
สำหรับไมโครซอฟท์คนอื่น ๆ -Werror
ส่วนใหญ่ใช้ ไม่ว่าในกรณีใดการรวบรวมข้อมูลจะล้มเหลวหากมีคำเตือนเกิดขึ้น
C คือชื่อเสียงภาษาระดับค่อนข้างต่ำเป็น HLLs ไป C ++ ถึงแม้ว่ามันอาจจะเป็นภาษาระดับสูงกว่า C มาก แต่ก็ยังคงแบ่งลักษณะไว้เป็นจำนวนมาก และหนึ่งในคุณลักษณะเหล่านั้นคือภาษาที่ถูกออกแบบโดยโปรแกรมเมอร์สำหรับโปรแกรมเมอร์ - และโดยเฉพาะโปรแกรมเมอร์ที่รู้ว่าพวกเขากำลังทำอะไร
[สำหรับส่วนที่เหลือของคำตอบนี้ฉันจะให้ความสำคัญกับ C. สิ่งที่ฉันจะพูดส่วนใหญ่จะใช้กับ C ++ ด้วยแม้ว่าอาจจะไม่รุนแรงก็ตาม แม้ว่าในขณะที่ Bjarne Stroustrup ได้กล่าวถึงชื่อเสียงว่า"C ทำให้มันง่ายในการถ่ายภาพตัวเองที่เท้า C ++ ทำให้มันยากขึ้น ]
ถ้าคุณรู้ว่าสิ่งที่คุณกำลังทำ - จริงๆรู้ว่าสิ่งที่คุณกำลังทำ - บางครั้งคุณอาจจะต้อง "แหกกฎ" แต่ส่วนใหญ่เราส่วนใหญ่จะยอมรับว่ากฎที่เจตนาดีช่วยให้เราหมดปัญหาและการละเมิดกฎเหล่านั้นตลอดเวลาเป็นความคิดที่ไม่ดี
แต่ใน C และ C ++ มีหลายสิ่งหลายอย่างที่คุณสามารถทำได้นั่นคือ "ความคิดที่ไม่ดี" แต่สิ่งที่ไม่เป็นทางการ "กับกฎ" บางครั้งพวกเขาก็เป็นความคิดที่ไม่ดีบางครั้ง (แต่อาจจะป้องกันได้อีกครั้ง); บางครั้งพวกเขาก็เป็นความคิดที่ไม่ดีตลอดเวลา แต่ประเพณีก็ไม่ได้เตือนเสมอเกี่ยวกับสิ่งเหล่านี้ - เพราะอีกครั้งข้อสันนิษฐานคือโปรแกรมเมอร์รู้ว่าพวกเขากำลังทำอะไรพวกเขาจะไม่ทำสิ่งเหล่านี้โดยไม่มีเหตุผลที่ดีพวกเขาจะรำคาญโดยกลุ่ม คำเตือนที่ไม่จำเป็น
แต่แน่นอนไม่ได้เขียนโปรแกรมทั้งหมดจริงๆรู้ว่าสิ่งที่พวกเขากำลังทำ และโดยเฉพาะอย่างยิ่งโปรแกรมเมอร์ C ทุกคน (ไม่ว่าจะมีประสบการณ์มากน้อยเพียงใด) จะต้องผ่านขั้นตอนของการเป็นโปรแกรมเมอร์ซีจุดเริ่มต้น และแม้แต่โปรแกรมเมอร์ C ที่มีประสบการณ์ก็สามารถประมาทและทำผิดพลาดได้
ท้ายที่สุดประสบการณ์ได้แสดงให้เห็นแล้วว่าโปรแกรมเมอร์ไม่ได้ทำผิดพลาด แต่ความผิดพลาดเหล่านี้อาจมีผลที่ตามมาอย่างแท้จริง หากคุณทำผิดพลาดและคอมไพเลอร์ไม่เตือนคุณเกี่ยวกับมันและอย่างใดโปรแกรมไม่ผิดพลาดทันทีหรือทำอะไรผิดอย่างเห็นได้ชัดเพราะมันความผิดพลาดสามารถแฝงตัวอยู่ที่นั่นซ่อนบางครั้งเป็นเวลาหลายปีจนกว่ามันจะทำให้จริงๆปัญหาใหญ่
ดังนั้นปรากฎว่าส่วนใหญ่คำเตือนเป็นความคิดที่ดีหลังจากทั้งหมด แม้แต่โปรแกรมเมอร์ที่มีประสบการณ์ก็เรียนรู้ (ที่จริงแล้วมันคือ " โดยเฉพาะโปรแกรมเมอร์ที่มีประสบการณ์ได้เรียนรู้") ว่าคำเตือนมีแนวโน้มที่จะดีกว่าอันตราย สำหรับทุกครั้งที่คุณทำสิ่งผิดพลาดโดยเจตนาและคำเตือนเป็นเรื่องน่ารำคาญอาจมีอย่างน้อยสิบครั้งที่คุณทำสิ่งผิดพลาดโดยบังเอิญและคำเตือนช่วยให้คุณรอดจากปัญหาอื่น ๆ และคำเตือนส่วนใหญ่สามารถปิดใช้งานหรือแก้ไขได้ในช่วงเวลาที่คุณต้องการทำสิ่งที่ "ผิด" จริงๆ
(ตัวอย่างคลาสสิกเช่น "ความผิดพลาด" คือการทดสอบif(a = b)
ส่วนใหญ่เวลานี้เป็นข้อผิดพลาดดังนั้นคอมไพเลอร์มากที่สุดวันนี้เตือนเกี่ยวกับมัน -.. บางคนโดยค่าเริ่มต้น แต่ถ้าคุณจริงๆอยากจะกำหนดทั้งb
ไปa
และการทดสอบ ผลลัพธ์คุณสามารถปิดใช้งานคำเตือนโดยพิมพ์if((a = b))
)
คำถามที่สองคือทำไมคุณต้องการถามคอมไพเลอร์ให้ปฏิบัติต่อคำเตือนว่าเป็นข้อผิดพลาด? ฉันบอกว่ามันเป็นเพราะธรรมชาติของมนุษย์โดยเฉพาะปฏิกิริยาที่ง่ายเกินไปในการพูดว่า "โอ้นั่นเป็นเพียงคำเตือนนั่นไม่สำคัญเลยฉันจะทำความสะอาดในภายหลัง" แต่ถ้าคุณเป็น procrastinator (และฉันไม่รู้เกี่ยวกับคุณ แต่ฉันเป็นprocrastinator ที่แย่มาก ) มันง่ายที่จะกำจัดการทำความสะอาดที่จำเป็นโดยทั่วไป - และถ้าคุณติดนิสัยการเพิกเฉยต่อคำเตือน รับง่ายขึ้นและง่ายขึ้นที่จะพลาดข้อความเตือนสำคัญที่กำลังนั่งอยู่ไม่มีใครสังเกตเห็นท่ามกลางสิ่งที่คุณไม่สนใจ
ดังนั้นการขอให้คอมไพเลอร์ปฏิบัติต่อคำเตือนเนื่องจากข้อผิดพลาดเป็นเคล็ดลับเล็ก ๆ น้อย ๆ ที่คุณสามารถเล่นด้วยตัวคุณเองเพื่อกำจัดมนุษย์คนนี้
โดยส่วนตัวฉันไม่ได้ยืนยันว่าจะปฏิบัติต่อคำเตือนว่าเป็นข้อผิดพลาด (อันที่จริงถ้าฉันซื่อสัตย์ฉันสามารถพูดได้ว่าฉันแทบไม่เคยเปิดใช้งานตัวเลือกนั้นในการเขียนโปรแกรม "ส่วนตัว" ของฉัน) แต่คุณสามารถมั่นใจได้ว่าฉันมีตัวเลือกที่เปิดใช้งานในที่ทำงานซึ่งเป็นแนวทางสไตล์ของเรา เขียน) เอกสารที่ใช้ และฉันจะบอกว่า - ฉันสงสัยว่าโปรแกรมเมอร์มืออาชีพส่วนใหญ่จะพูดว่า - ร้านค้าใด ๆ ที่ไม่จัดการกับคำเตือนเนื่องจากข้อผิดพลาดใน C ทำงานโดยไม่มีความรับผิดชอบไม่ยึดถือแนวปฏิบัติที่ดีที่สุดในอุตสาหกรรมที่ยอมรับกันทั่วไป
if(a = b)
ได้ดังนั้นเราจึงไม่จำเป็นต้องเตือนเรื่องนี้" (มีคนสร้างรายการข้อผิดพลาดร้ายแรง 10 รายการใน 10 ผลิตภัณฑ์ที่วางจำหน่ายซึ่งเป็นผลมาจากข้อผิดพลาดนี้) "โอเคไม่มีโปรแกรมเมอร์ C ที่มีประสบการณ์จะเขียนว่า ... "
if (returnCodeFromFoo = foo(bar))
และหมายถึงมันเพื่อจับและทดสอบโค้ดในที่เดียว (สมมติว่าจุดประสงค์เดียวของfoo
การมีผลข้างเคียง!) ความจริงที่ว่าโปรแกรมเมอร์ที่มีประสบการณ์จริงๆอาจรู้ว่านี่ไม่ใช่ สไตล์การเขียนโค้ดที่ดีนั้นอยู่ด้านข้างจุด)
if (returnCodeFromFoo = foo(bar))
พวกเขาก็ใส่ความคิดเห็นและปิดคำเตือน (เพื่อให้เมื่อโปรแกรมเมอร์บำรุงรักษามองมันในอีก 4 ปีต่อมาเขา / เธอจะรู้ว่ารหัสนั้นเป็นความตั้งใจนั่นคือฉันทำงาน กับคนที่อยู่ใน (ในที่ดินของ Microsoft C ++) ยืนยันว่าการรวม / Wall กับการจัดการคำเตือนเป็นข้อผิดพลาดเป็นวิธีที่จะไปเอ่อมันไม่ได้ (เว้นแต่คุณต้องการใส่ความคิดเห็นในการปราบปรามจำนวนมาก)
คำเตือนประกอบด้วยคำแนะนำที่ดีที่สุดนักพัฒนา C ++ ที่มีทักษะมากที่สุดสามารถอบเข้าไปในแอปพลิเคชัน พวกเขาน่าจะเก็บไว้รอบ ๆ
C ++ ซึ่งเป็นภาษาทัวริงที่สมบูรณ์มีหลายกรณีที่คอมไพเลอร์ต้องเชื่อมั่นว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่ อย่างไรก็ตามมีหลายกรณีที่คอมไพเลอร์สามารถตระหนักได้ว่าคุณอาจไม่ได้ตั้งใจจะเขียนสิ่งที่คุณเขียน ตัวอย่างคลาสสิกเป็น printf () รหัสซึ่งไม่ตรงกับข้อโต้แย้งหรือมาตรฐาน :: สตริงส่งผ่านไปยัง printf (ไม่ได้ว่าเคยเกิดขึ้นกับฉัน!) ในกรณีเหล่านี้รหัสที่คุณเขียนไม่ใช่ข้อผิดพลาด เป็นนิพจน์ C ++ ที่ถูกต้องพร้อมการตีความที่ถูกต้องเพื่อให้คอมไพเลอร์ดำเนินการ แต่คอมไพเลอร์มีลางสังหรณ์ที่แข็งแกร่งซึ่งคุณมองข้ามบางสิ่งซึ่งเป็นเรื่องง่ายสำหรับคอมไพเลอร์สมัยใหม่ในการตรวจจับ นี่คือคำเตือน พวกเขาเป็นสิ่งที่เห็นได้ชัดกับคอมไพเลอร์โดยใช้กฎที่เข้มงวดของ C ++ ในการกำจัดของที่คุณอาจมองข้าม
การปิดคำเตือนหรือเพิกเฉยต่อคำเตือนนั้นก็เหมือนกับการเลือกที่จะเพิกเฉยต่อคำแนะนำฟรีจากผู้ที่มีทักษะมากกว่าคุณ มันเป็นบทเรียนในฮูเบอร์ที่จบลงเมื่อคุณบินใกล้กับดวงอาทิตย์และปีกของคุณละลายมากเกินไปหรือเกิดข้อผิดพลาดเกี่ยวกับความจำเสื่อม ระหว่างสองฉันจะตกลงมาจากท้องฟ้าทุกวัน!
"ปฏิบัติต่อคำเตือนว่าเป็นข้อผิดพลาด" เป็นรุ่นที่สูงที่สุดของปรัชญานี้ ความคิดที่นี่คือคุณแก้ไขทุกคำเตือนคอมไพเลอร์ให้คุณ - คุณฟังคำแนะนำฟรีทุกบิตและดำเนินการกับมัน ไม่ว่าจะเป็นรูปแบบที่ดีสำหรับการพัฒนาสำหรับคุณขึ้นอยู่กับทีมและผลิตภัณฑ์ที่คุณกำลังทำงานอยู่ มันเป็นวิธีการที่นักพรตที่พระอาจมี สำหรับบางคนมันใช้งานได้ดี สำหรับคนอื่นมันไม่ได้
ในแอปพลิเคชันของฉันจำนวนมากเราไม่ถือว่าคำเตือนเป็นข้อผิดพลาด เราทำเช่นนี้เพราะแอปพลิเคชันเหล่านี้จำเป็นต้องรวบรวมในหลาย ๆ แพลตฟอร์มที่มีคอมไพเลอร์หลายช่วงอายุที่แตกต่างกัน บางครั้งเราพบว่าเป็นไปไม่ได้ที่จะแก้ไขคำเตือนในด้านหนึ่งโดยที่มันไม่ได้เปลี่ยนเป็นการเตือนบนแพลตฟอร์มอื่น ดังนั้นเราแค่ระวัง เราเคารพคำเตือน แต่เราไม่โค้งไปข้างหลังสำหรับพวกเขา
equals
/ hashCode
) และเป็นปัญหาคุณภาพของการใช้งานที่มีการรายงาน
การจัดการคำเตือนไม่เพียงทำให้โค้ดดีขึ้นเท่านั้น แต่ยังทำให้คุณเป็นโปรแกรมเมอร์ที่ดีขึ้นอีกด้วย คำเตือนจะบอกคุณเกี่ยวกับสิ่งต่าง ๆ ที่อาจดูเล็กน้อยสำหรับคุณในวันนี้ แต่วันหนึ่งนิสัยที่ไม่ดีจะกลับมากัดหัวของคุณ
ใช้ประเภทที่ถูกต้องส่งคืนค่านั้นประเมินค่าที่ส่งคืน ใช้เวลาและใคร่ครวญว่า "นี่เป็นประเภทที่ถูกต้องจริงๆในบริบทนี้หรือไม่" "ฉันต้องส่งคืนสิ่งนี้หรือไม่" และตัวใหญ่; "รหัสนี้จะพกพาได้ในอีก 10 ปีข้างหน้าหรือไม่"
เริ่มเขียนโค้ดที่ไม่มีคำเตือนตั้งแต่แรก
คำตอบอื่น ๆ นั้นยอดเยี่ยมและฉันไม่ต้องการพูดซ้ำสิ่งที่พวกเขาพูด
อีกแง่มุมหนึ่งของ "ทำไมจึงเปิดใช้งานคำเตือน" ที่ไม่ได้สัมผัสอย่างถูกต้องคือพวกเขาช่วยอย่างมากกับการบำรุงรักษาโค้ด เมื่อคุณเขียนโปรแกรมที่มีขนาดใหญ่มันเป็นไปไม่ได้เลยที่จะเก็บเรื่องทั้งหมดไว้ในหัวของคุณทันที โดยทั่วไปคุณมีฟังก์ชั่นหรือสามอย่างที่คุณกำลังเขียนและคิดอย่างแข็งขันและอาจเป็นไฟล์หรือสามบนหน้าจอที่คุณสามารถอ้างถึงได้ แต่ส่วนใหญ่ของโปรแกรมอยู่ในพื้นหลังและคุณต้องเชื่อมั่น ทำงานต่อไป
การมีคำเตือนและทำให้พวกเขากระตือรือร้นและอยู่ในใบหน้าของคุณให้มากที่สุดจะช่วยเตือนคุณหากสิ่งที่คุณเปลี่ยนมีปัญหากับบางสิ่งที่คุณมองไม่เห็น
-Wswitch-enum
ใช้ตัวอย่างเช่นคำเตือนเสียงดังกราว สิ่งนั้นจะเป็นตัวเตือนถ้าคุณใช้สวิตช์บน enum และพลาดหนึ่งในค่า enum ที่เป็นไปได้ เป็นสิ่งที่คุณอาจคิดว่าเป็นความผิดพลาดที่ไม่น่าจะเกิดขึ้น: อย่างน้อยคุณอาจดูรายการค่า enum เมื่อคุณเขียนคำสั่ง switch คุณอาจมี IDE ที่สร้างตัวเลือกสวิตช์ให้คุณโดยไม่มีที่ว่างสำหรับความผิดพลาดของมนุษย์
คำเตือนนี้มาเป็นของตัวเองเมื่อหกเดือนต่อมาคุณเพิ่มอีกรายการที่เป็นไปได้เพื่อ enum อีกครั้งหากคุณกำลังคิดเกี่ยวกับรหัสที่เป็นปัญหาคุณอาจไม่เป็นอะไร แต่ถ้า enum นี้ใช้เพื่อจุดประสงค์ที่แตกต่างกันและเป็นหนึ่งในสิ่งที่คุณต้องการตัวเลือกพิเศษมันง่ายมากที่จะลืมอัปเดตสวิตช์ในไฟล์ที่คุณไม่ได้สัมผัสเป็นเวลา 6 เดือน
คุณสามารถนึกถึงคำเตือนในลักษณะเดียวกับที่คุณนึกถึงกรณีทดสอบอัตโนมัติ: ช่วยให้คุณมั่นใจได้ว่ารหัสนั้นสมเหตุสมผลและทำในสิ่งที่คุณต้องการเมื่อคุณเขียนครั้งแรก แต่ช่วยได้มากขึ้นเพื่อให้แน่ใจว่า ทำสิ่งที่คุณต้องการต่อไปในขณะที่คุณแยงมัน ความแตกต่างคือกรณีทดสอบนั้นแคบมากตามความต้องการของรหัสของคุณและคุณต้องเขียนพวกเขาในขณะที่คำเตือนนั้นทำงานได้มาตรฐานที่สมเหตุสมผลสำหรับรหัสเกือบทั้งหมดและพวกเขาได้รับแรงบันดาลใจจาก boffins ที่ทำคอมไพล์
ตัวอย่างเช่นการดีบักความผิดพลาดในการแบ่งส่วนต้องการให้โปรแกรมเมอร์ทำการติดตามรูท (สาเหตุ) ของความผิดปกติซึ่งมักจะอยู่ในตำแหน่งก่อนหน้าในรหัสของคุณมากกว่าบรรทัดที่ทำให้เกิดความผิดพลาดในการแบ่งส่วน
เป็นเรื่องปกติมากที่สาเหตุเป็นบรรทัดที่คอมไพเลอร์ได้ออกคำเตือนว่าคุณไม่สนใจและบรรทัดที่ทำให้การแบ่งเซ็กเมนต์เกิดความผิดพลาดบรรทัดที่โยนข้อผิดพลาดในที่สุด
การแก้ไขคำเตือนนำไปสู่การแก้ไขปัญหา .. คลาสสิก!
การสาธิตด้านบน .. พิจารณารหัสต่อไปนี้:
#include <stdio.h>
int main(void) {
char* str = "Hello world!";
int idx;
// Colossal amount of code here, irrelevant to 'idx'
printf("%c\n", str[idx]);
return 0;
}
ซึ่งเมื่อคอมไพล์ด้วยแฟล็ก "Wextra" ที่ส่งผ่านไปยัง GCC จะให้
main.c: In function 'main':
main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
9 | printf("%c\n", str[idx]);
| ^
ซึ่งฉัน สามารถละเว้นและรันรหัสต่อไป .. และจากนั้นฉันจะได้เห็นข้อผิดพลาดการแบ่งส่วน "ยิ่งใหญ่" เนื่องจากศาสตราจารย์ epicurus IP ของฉันเคยพูดว่า:
การแบ่งส่วนความผิด
ในการแก้ไขข้อบกพร่องในสถานการณ์โลกแห่งความเป็นจริงใครจะเริ่มจากบรรทัดที่ทำให้เกิดการแบ่งส่วนและพยายามที่จะติดตามว่าอะไรคือสาเหตุของสาเหตุ ... พวกเขาจะต้องค้นหาสิ่งที่เกิดขึ้น i
และstr
ภายในว่าจำนวนเงินมหาศาล ของรหัสที่นั่น ...
จนกระทั่งวันหนึ่งพวกเขาพบว่าตนเองอยู่ในสถานการณ์ที่พวกเขาค้นพบสิ่งนั้น idx
มีการใช้งานที่ไม่ได้กำหนดค่าเริ่มต้นดังนั้นจึงมีค่าขยะซึ่งส่งผลให้มีการจัดทำดัชนีสตริง (วิธี) เกินขอบเขตซึ่งนำไปสู่
หากเพียง แต่พวกเขาไม่เพิกเฉยต่อคำเตือนพวกเขาก็จะพบข้อผิดพลาดทันที!
str[idx]
" ไม่ใช่ "โอเคอยู่ที่ไหนstr
และidx
ถูกกำหนดหรือไม่`
idx
เป็นค่าที่คุณคาดหวังจากการทดสอบของคุณ (ไม่น่าเป็นไปได้ถ้าค่าที่คาดไว้คือ 0) และจริง ๆ แล้วชี้ไปที่ข้อมูลสำคัญที่ไม่ควรพิมพ์เมื่อนำไปใช้งาน
การปฏิบัติตามคำเตือนเป็นข้อผิดพลาดเป็นเพียงวิธีการมีวินัยในตนเอง: คุณได้รวบรวมโปรแกรมเพื่อทดสอบคุณลักษณะใหม่ที่เป็นประกาย แต่คุณทำไม่ได้จนกว่าคุณจะแก้ไขส่วนที่เลอะเทอะ ไม่มีข้อมูลเพิ่มเติมใดWerror
ๆ เพียงกำหนดลำดับความสำคัญอย่างชัดเจน:
อย่าเพิ่มรหัสใหม่จนกว่าคุณจะแก้ไขปัญหาในรหัสที่มีอยู่
มันเป็นความคิดที่สำคัญไม่ใช่เครื่องมือ เอาต์พุตการวินิจฉัยคอมไพเลอร์เป็นเครื่องมือ MISRA (สำหรับ C ที่ฝัง) เป็นเครื่องมืออื่น มันไม่สำคัญว่าคุณจะใช้แบบไหน แต่คำเตือนของคอมไพเลอร์เป็นเครื่องมือที่ง่ายที่สุดที่คุณจะได้รับ (เป็นเพียงหนึ่งการตั้งค่า) และอัตราส่วนสัญญาณต่อสัญญาณรบกวนนั้นสูงมาก ดังนั้นจึงไม่มีเหตุผลที่จะไม่ใช้มัน
ไม่มีเครื่องมือที่ผิดพลาด หากคุณเขียนconst float pi = 3.14;
เครื่องมือส่วนใหญ่จะไม่บอกคุณว่าคุณกำหนดπด้วยความแม่นยำที่ไม่ดีซึ่งอาจนำไปสู่ปัญหาตามมา เครื่องมือส่วนใหญ่จะไม่ยกคิ้วif(tmp < 42)
แม้ว่าจะเป็นที่รู้กันดีว่าการตั้งชื่อตัวแปรที่ไม่มีความหมายและการใช้เลขเวทเป็นวิธีหนึ่งที่จะหายนะในโครงการขนาดใหญ่ คุณต้องเข้าใจว่ารหัส "การทดสอบอย่างรวดเร็ว" ที่คุณเขียนนั้นก็คือ: การทดสอบและคุณต้องทำให้ถูกต้องก่อนที่คุณจะย้ายไปทำงานอื่นในขณะที่คุณยังเห็นข้อบกพร่องอยู่ หากคุณปล่อยให้รหัสนั้นเป็นเช่นนั้นการดีบั๊กถ้าหลังจากคุณใช้เวลาสองเดือนในการเพิ่มคุณสมบัติใหม่จะยากขึ้นอย่างมาก
Werror
เมื่อคุณได้รับเป็นความคิดที่ถูกต้องมีจุดในการใช้ไม่มี การมีคำเตือนเป็นคำเตือนจะช่วยให้คุณสามารถตัดสินใจได้อย่างชาญฉลาดไม่ว่าจะยังคงเหมาะสมที่จะใช้เซสชันการดีบักที่คุณกำลังจะเริ่มหรือยกเลิกและแก้ไขคำเตือนก่อน
clippy
เครื่องมือสำหรับผ้าสำลีสำหรับสนิมจริง ๆ จะเตือนเกี่ยวกับค่าคงที่ "3.14" มันเป็นเรื่องจริงเช่นในเอกสาร แต่อย่างที่คุณเดาจากชื่อจงclippy
ภูมิใจในการเป็นประโยชน์อย่างจริงจัง
ในฐานะคนที่ทำงานกับรหัสฝังตัว C แบบดั้งเดิมการเปิดใช้งานคำเตือนคอมไพเลอร์ได้ช่วยแสดงจุดอ่อนและพื้นที่จำนวนมากในการตรวจสอบเมื่อเสนอการแก้ไข ในการใช้ gcc -Wall
และ-Wextra
และ-Wshadow
ได้กลายเป็นสิ่งสำคัญ ฉันจะไม่ไปกับอันตรายทุกอย่าง แต่ฉันจะแสดงรายการที่โผล่ขึ้นมาซึ่งช่วยแสดงรหัสปัญหา
สิ่งนี้สามารถชี้ไปที่งานที่ยังไม่เสร็จและพื้นที่ที่อาจไม่สามารถใช้ตัวแปรที่ส่งผ่านทั้งหมดซึ่งอาจเป็นปัญหาได้ ลองดูฟังก์ชั่นง่ายๆที่อาจทำให้เกิดสิ่งนี้:
int foo(int a, int b)
{
int c = 0;
if (a > 0)
{
return a;
}
return 0;
}
เพียงแค่รวบรวมสิ่งนี้โดยไม่มี -Wall หรือ -Wextra ส่งคืนไม่มีปัญหา - จะแจ้งให้คุณทราบแม้ว่าc
จะไม่เคยใช้:
foo.c: ในฟังก์ชั่น 'foo':
foo.c: 9: 20: คำเตือน: ตัวแปรที่ไม่ได้ใช้ 'c' [-Wunused-variable]
- Textra จะบอกคุณด้วยว่าพารามิเตอร์ b ของคุณไม่ได้ทำอะไรเลย:
foo.c: ในฟังก์ชั่น 'foo':
foo.c: 9: 20: คำเตือน: ตัวแปรที่ไม่ได้ใช้ 'c' [-Wunused-variable]
foo.c: 7: 20: คำเตือน: พารามิเตอร์ที่ไม่ได้ใช้ 'b' [-Wunused-parameter] int foo (int a, int b)
หนึ่งบิตนี้ยากและไม่ปรากฏจนกว่าจะ-Wshadow
ถูกนำมาใช้ ลองปรับเปลี่ยนตัวอย่างด้านบนเพื่อเพิ่ม แต่เกิดขึ้นเป็นโลกที่มีชื่อเดียวกันกับท้องถิ่นซึ่งทำให้เกิดความสับสนมากเมื่อพยายามใช้ทั้งสองอย่าง
int c = 7;
int foo(int a, int b)
{
int c = a + b;
return c;
}
เมื่อ -Wshadow เปิดใช้งานมันจะเห็นปัญหานี้ได้ง่าย
foo.c: 11: 9: คำเตือน: การประกาศ 'c' เงาการประกาศทั่วโลก [-Wshadow]
foo.c: 1: 5: หมายเหตุ: การประกาศที่มีเงาอยู่ที่นี่
สิ่งนี้ไม่จำเป็นต้องมีการตั้งค่าสถานะพิเศษเป็น gcc แต่มันยังคงเป็นต้นเหตุของปัญหาในอดีต ฟังก์ชั่นง่าย ๆ ที่พยายามพิมพ์ข้อมูล แต่มีข้อผิดพลาดในการจัดรูปแบบอาจมีลักษณะเช่นนี้:
void foo(const char * str)
{
printf("str = %d\n", str);
}
สิ่งนี้จะไม่พิมพ์สตริงเนื่องจากการจัดรูปแบบธงผิดและ gcc จะบอกคุณอย่างมีความสุขว่านี่อาจไม่ใช่สิ่งที่คุณต้องการ:
foo.c: ในฟังก์ชั่น 'foo':
foo.c: 10: 12: คำเตือน: รูปแบบ '% d' คาดว่าจะโต้แย้งประเภท 'int' แต่ข้อโต้แย้งที่ 2 มีประเภท 'const char *' [-Wformat =]
นี่เป็นเพียงสามสิ่งที่คอมไพเลอร์สามารถตรวจสอบได้อีกครั้งสำหรับคุณ มีคนอื่นอีกหลายคนที่ชอบใช้ตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้นที่คนอื่น ๆ ได้ชี้ให้เห็น
possible loss of precision
" และ " comparison between signed and unsigned
" ฉันพบว่ามันยากที่จะเข้าใจว่า "โปรแกรมเมอร์" เพิกเฉยต่อสิ่งเหล่านี้ (ในความเป็นจริงฉันไม่แน่ใจว่าทำไมพวกเขาถึงไม่ใช่ข้อผิดพลาด)
sizeof
ไม่ได้ลงนาม แต่ประเภทจำนวนเต็มเริ่มต้นมีการลงนาม sizeof
ประเภทผลsize_t
เป็นที่มักจะใช้สำหรับสิ่งที่เกี่ยวข้องกับขนาดชนิดเช่นเช่นการนับการจัดตำแหน่งหรืออาร์เรย์ / ภาชนะบรรจุองค์ประกอบขณะจำนวนเต็มโดยทั่วไปมีความตั้งใจที่จะใช้เป็น " int
เว้นแต่มีความจำเป็นเป็นอย่างอื่น" พิจารณาว่ามีคนกี่คนที่ได้รับการสอนให้ใช้int
ย้ำเหนือตู้คอนเทนเนอร์ของพวกเขา (เทียบint
กับsize_t
) ทำให้เกิดข้อผิดพลาดจะทำให้ทุกอย่างคร่าวๆ ; P
นี่คือคำตอบเฉพาะสำหรับ C และทำไมสิ่งนี้จึงสำคัญต่อ C มากกว่าสิ่งอื่นใด
#include <stdio.h>
int main()
{
FILE *fp = "some string";
}
รหัสนี้จะรวบรวมพร้อมกับคำเตือน สิ่งที่ควรและเป็นข้อผิดพลาดในภาษาอื่น ๆ บนโลกทุกภาษา (ยกเว้นภาษาแอสเซมบลี) คือคำเตือนใน C. คำเตือนใน C มักจะมีข้อผิดพลาดในการปลอมตัว คำเตือนควรได้รับการแก้ไขไม่ถูกระงับ
ด้วยเราทำเช่นนี้gcc
gcc -Wall -Werror
นี่ก็เป็นเหตุผลสำหรับความไม่พอใจสูงเกี่ยวกับคำเตือน API ที่ไม่ปลอดภัยของ MS คนส่วนใหญ่การเขียนโปรแกรม C ได้เรียนรู้วิธีที่ยากในการจัดการคำเตือนว่าเป็นข้อผิดพลาดและสิ่งนี้ดูเหมือนว่าไม่ใช่สิ่งเดียวกันและต้องการการแก้ไขที่ไม่ใช่แบบพกพา
คำเตือนของคอมไพเลอร์เป็นเพื่อนของคุณ (ไม่ใช่ตะโกนเรียกตัวพิมพ์ใหญ่เพื่อเน้น)
ฉันทำงานกับระบบ Fortran-77 รุ่นเก่า คอมไพเลอร์บอกสิ่งที่มีค่ากับฉัน: อาร์กิวเมนต์ประเภทข้อมูลไม่ตรงกันในการเรียกรูทีนย่อยโดยใช้ตัวแปรโลคัลก่อนที่ค่าจะถูกตั้งเป็นตัวแปรถ้าฉันมีอาร์กิวเมนต์ตัวแปรหรือรูทีนย่อยที่ไม่ได้ใช้ นี่เป็นข้อผิดพลาดเกือบทุกครั้ง
หลีกเลี่ยงการโพสต์ยาว: เมื่อรหัสของฉันรวบรวมได้อย่างสมบูรณ์ 97% จะทำงาน อีกคนที่ฉันทำงานด้วยคอมไพล์โดยปิดคำเตือนทั้งหมดใช้เวลาหลายชั่วโมงหรือหลายวันในดีบักเกอร์จากนั้นขอให้ฉันช่วย ฉันแค่รวบรวมรหัสของเขาโดยมีคำเตือนแล้วบอกเขาว่าจะแก้ไขอะไร
คุณควรเปิดใช้งานคำเตือนคอมไพเลอร์เสมอเพราะคอมไพเลอร์สามารถบอกได้ว่ามีอะไรผิดปกติกับรหัสของคุณ เมื่อต้องการทำเช่นนี้คุณผ่าน-Wall -Wextra
จะไปยังคอมไพเลอร์
คุณควรปฏิบัติต่อคำเตือนเป็นข้อผิดพลาดเนื่องจากคำเตือนมักจะมีความหมายว่ามีบางอย่างผิดปกติกับรหัสของคุณ อย่างไรก็ตามมักจะง่ายที่จะละเว้นข้อผิดพลาดเหล่านี้ ดังนั้นการถือว่าพวกเขาเป็นข้อผิดพลาดจะทำให้การสร้างล้มเหลวดังนั้นคุณจึงไม่สามารถละเลยข้อผิดพลาดได้ ในการจัดการกับคำเตือนว่าเป็นข้อผิดพลาดให้ส่ง-Werror
ไปยังคอมไพเลอร์
คำเตือนคอมไพเลอร์ใน C ++ มีประโยชน์มากด้วยเหตุผลบางประการ
1 - อนุญาตให้แสดงตำแหน่งที่คุณสามารถทำผิดที่สามารถส่งผลต่อผลลัพธ์สุดท้ายของการดำเนินการของคุณ ตัวอย่างเช่นถ้าคุณไม่ได้เริ่มต้นตัวแปรหรือถ้าคุณใส่ "=" แทน "==" (มีเพียงตัวอย่าง)
2 - อนุญาตให้แสดงรหัสของคุณที่ไม่สอดคล้องกับมาตรฐานของ c ++ มันมีประโยชน์เพราะถ้ารหัสนั้นเป็นไปตามมาตรฐานจริงมันจะง่ายต่อการย้ายรหัสไปยัง plateform อื่น ๆ เช่น
โดยทั่วไปคำเตือนมีประโยชน์มากในการแสดงให้คุณเห็นว่าคุณมีข้อผิดพลาดในรหัสของคุณที่สามารถส่งผลต่อผลลัพธ์ของอัลกอริทึมของคุณหรือป้องกันข้อผิดพลาดบางอย่างเมื่อผู้ใช้จะใช้โปรแกรมของคุณ
การเพิกเฉยต่อคำเตือนหมายถึงคุณทิ้งโค้ดเลอะเทอะซึ่งไม่เพียง แต่จะทำให้เกิดปัญหากับคนอื่นในอนาคต แต่ยังจะทำให้ข้อความที่สำคัญในการคอมไพล์สังเกตเห็นได้น้อยลง คอมไพเลอร์เอาท์พุทที่มากขึ้นทุกคนที่น้อยลงจะสังเกตเห็นหรือรำคาญ ทำความสะอาดดีกว่า นอกจากนี้ยังหมายความว่าคุณรู้ว่าคุณกำลังทำอะไรอยู่ คำเตือนไม่เป็นมืออาชีพประมาทและเสี่ยง
ฉันเคยทำงานให้กับ บริษัท ขนาดใหญ่ (Fortune 50) ที่ผลิตอุปกรณ์ทดสอบอิเล็กทรอนิกส์
ผลิตภัณฑ์หลักของกลุ่มของฉันคือโปรแกรม MFC ที่ในช่วงหลายปีที่ผ่านมาเพื่อสร้างคำเตือนหลายร้อยตัว ซึ่งถูกเพิกเฉยในเกือบทุกกรณี
นี่คือฝันร้าย frigging เมื่อข้อบกพร่องเกิดขึ้น
หลังจากตำแหน่งนั้นฉันโชคดีที่ได้รับการว่าจ้างให้เป็นผู้พัฒนารายแรกในการเริ่มต้นใหม่
ฉันสนับสนุนนโยบาย 'ไม่มีคำเตือน' สำหรับการสร้างทั้งหมดโดยมีระดับคำเตือนคอมไพเลอร์ตั้งเป็นเสียงดัง
การปฏิบัติของเราคือการใช้คำเตือน #pragma - กด / ปิดการใช้งาน / ป๊อปอัพสำหรับรหัสที่นักพัฒนาแน่ใจว่าใช้ได้จริงพร้อมด้วยคำสั่งบันทึกที่ระดับการดีบักในกรณีนี้
วิธีนี้ใช้ได้ผลดีสำหรับเรา
#pragma warning
ไม่เพียง แต่ยับยั้งคำเตือนเท่านั้นมันมีจุดประสงค์สองอย่างในการสื่อสารกับโปรแกรมเมอร์อื่น ๆ อย่างรวดเร็วว่าสิ่งที่ตั้งใจและไม่ตั้งใจและทำหน้าที่เป็นแท็กการค้นหาเพื่อค้นหาพื้นที่ที่อาจเป็นปัญหาได้อย่างรวดเร็วเมื่อมีบางสิ่งผิดพลาด ซ่อมมัน.
คำเตือนคือข้อผิดพลาดที่รอให้เกิดขึ้น ดังนั้นคุณต้องเปิดใช้งานคำเตือนคอมไพเลอร์และจัดระเบียบโค้ดของคุณเพื่อลบคำเตือนใด ๆ
มีเพียงเป็นหนึ่งในปัญหาเกี่ยวกับการรักษาคำเตือนเป็นข้อผิดพลาด: เมื่อคุณใช้โค้ดมาจากแหล่งอื่น ๆ (เช่นไมโคร $ ** ห้องสมุด T, โครงการโอเพ่นซอร์ส) พวกเขาไม่ได้ทำขวางานของพวกเขาและการรวบรวมรหัสของพวกเขาสร้างตันจากคำเตือน
ฉันมักจะเขียนรหัสของฉันเพื่อที่จะไม่สร้างคำเตือนหรือข้อผิดพลาดใด ๆ และทำความสะอาดมันจนกว่าจะรวบรวมโดยไม่สร้างเสียงรบกวนภายนอกใด ๆ ขยะฉันต้องทำงานกับ appalls ฉันและฉันประหลาดใจเมื่อฉันต้องสร้างโครงการขนาดใหญ่และดูกระแสของคำเตือนไปที่การรวบรวมควรจะประกาศไฟล์ที่ประมวลผลเท่านั้น
ฉันยังบันทึกรหัสของฉันเพราะฉันรู้ว่าค่าใช้จ่ายตลอดอายุการใช้งานจริงของซอฟต์แวร์ส่วนใหญ่มาจากการบำรุงรักษาไม่ใช่จากการเขียนในตอนแรก แต่นั่นเป็นเรื่องที่แตกต่าง ...
-Wall
-Wall -Wextra
คำเตือนบางอย่างอาจหมายถึงข้อผิดพลาดทางความหมายที่เป็นไปได้ในรหัสหรือ UB ที่เป็นไปได้ เช่น;
หลังจากif()
นั้นตัวแปรที่ไม่ได้ใช้ตัวแปรส่วนกลางถูกปิดบังโดยโลคัลหรือการเปรียบเทียบของที่ลงชื่อและไม่ได้ลงนาม คำเตือนจำนวนมากเกี่ยวข้องกับเครื่องวิเคราะห์รหัสแบบคงที่ในคอมไพเลอร์หรือการละเมิดมาตรฐาน ISO ที่ตรวจพบได้ในเวลารวบรวมซึ่ง "ต้องการการวินิจฉัย" ในขณะที่เหตุการณ์เหล่านั้นอาจถูกกฎหมายในบางกรณีพวกเขาจะเป็นผลมาจากปัญหาการออกแบบส่วนใหญ่
คอมไพเลอร์บางตัวเช่น gcc มีตัวเลือกบรรทัดคำสั่งเพื่อเปิดใช้งานโหมด "คำเตือนเป็นข้อผิดพลาด" มันดีถ้าเครื่องมือที่โหดร้ายเพื่อให้ความรู้แก่ผู้เริ่มหัดใช้มือใหม่
ความจริงที่ว่าคอมไพเลอร์ C ++ ยอมรับการคอมไพล์โค้ดที่เห็นได้ชัดว่ามีพฤติกรรมที่ไม่ได้กำหนดเลยเป็นข้อบกพร่องที่สำคัญในคอมไพเลอร์ เหตุผลที่พวกเขาไม่แก้ไขปัญหานี้ก็เพราะการทำเช่นนั้นอาจทำให้งานสร้างที่ใช้งานไม่ได้บางส่วน
คำเตือนส่วนใหญ่ควรเป็นข้อผิดพลาดร้ายแรงที่ทำให้การสร้างไม่เสร็จสมบูรณ์ ค่าเริ่มต้นสำหรับเพียงแสดงข้อผิดพลาดและสร้างส่วนต่อไปนั้นผิดและถ้าคุณไม่แทนที่พวกเขาเพื่อจัดการกับคำเตือนเป็นข้อผิดพลาดและออกจากคำเตือนบางอย่างคุณอาจจะจบลงด้วยโปรแกรมของคุณทำงานล้มเหลวและทำสิ่งต่าง ๆ แบบสุ่ม
int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];
นี้แสดงพฤติกรรมที่ไม่ได้กำหนดถ้าหากทั้งคู่fun1()
และfun2()
สามารถกลับมาfalse
ในการทำงานของฟังก์ชั่นเดียวกัน สิ่งใดที่อาจจริงหรือไม่จริง แต่คอมไพเลอร์จะบอกอย่างไร?
คุณควรเปิดใช้งานคำเตือนคอมไพเลอร์อย่างแน่นอนเนื่องจากคอมไพเลอร์บางตัวไม่ดีในการรายงานข้อผิดพลาดทั่วไปของการเขียนโปรแกรมรวมถึงสิ่งต่อไปนี้: -
-> กำหนดค่าเริ่มต้นให้กับตัวแปรที่ถูกลืม -> ส่งคืนค่าจากฟังก์ชันที่พลาด -> อาร์กิวเมนต์ง่าย ๆ ในตระกูล printf และ scanf ที่ไม่ตรงกับสตริงรูปแบบที่ฟังก์ชันใช้โดยไม่ต้องประกาศล่วงหน้าแม้ว่าจะเกิดขึ้นใน c เท่านั้น
ดังนั้นในขณะที่ฟังก์ชั่นเหล่านี้สามารถตรวจจับและรายงานได้โดยปกติแล้วจะไม่ใช่ตามค่าเริ่มต้น ดังนั้นคุณสมบัตินี้จะต้องได้รับการร้องขออย่างชัดเจนผ่านตัวเลือกคอมไพเลอร์
ใช้ง่าย: คุณไม่ต้องทำก็ไม่จำเป็น -Wall และ -Werror รับการออกแบบโดยบ้ารหัส refactoring สำหรับตัวเอง: มันถูกคิดค้นโดยนักพัฒนาคอมไพเลอร์ที่จะหลีกเลี่ยงการทำลายที่มีอยู่สร้างหลังจากการปรับปรุงคอมไพเลอร์ในด้านการใช้ คุณลักษณะไม่มีอะไร แต่ทั้งหมดเกี่ยวกับการตัดสินใจที่จะทำลายหรือไม่ทำลายการสร้าง
มันขึ้นอยู่กับความชอบของคุณที่จะใช้หรือไม่ ฉันใช้มันตลอดเวลาเพราะมันช่วยให้ฉันแก้ไขข้อผิดพลาดได้
-Wall and -Werror was designed by code-refactoring maniacs for themselves.
[จำเป็น]
-Wall
และ-Werror
เป็นเพียงการถามว่าเป็นความคิดที่ดีหรือไม่ ซึ่งจากประโยคสุดท้ายของคุณดูเหมือนว่าคุณกำลังพูดว่า