เหตุใดจึงควรปิดการใช้งานคำเตือนคอมไพเลอร์?


26

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

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


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

@Alastair Pitts: ฉันเสนอการย้ายไปยังโปรแกรมเมอร์ ฉันตระหนักถึงความผิดพลาดของฉันในภายหลัง
Tugrul Ates

3
ข้อความเตือนมีไว้สำหรับเหตุผลใช่ แต่ก็มีเหตุผลว่าทำไมพวกเขาถึงไม่ใช่ข้อความแสดงข้อผิดพลาด
โซโลมอนช้า

2
@james large ความคิดเห็นของคุณสรุปสถานการณ์อย่างดี คำเตือนคือคอมไพเลอร์ที่บอกคุณว่าสถานการณ์มีความผิดซึ่งอาจเป็นไปได้ ถ้ามันผิดอย่างแน่นอนมันจะเป็นข้อผิดพลาด เนื่องจากคำเตือนบางอย่างอาจเป็นผลบวกปลอมควรมีวิธีเขียนโค้ดเพื่อกำจัดคำเตือน น่าเสียดายที่บางครั้งวิธีปฏิบัติที่เป็นไปได้มากที่สุดก็คือการใช้วิธีปฏิบัติ ดังนั้นชื่อ
Eric Lippert

มันไม่ได้ปิดใช้งาน แต่ซ่อนอยู่ ปัญหาของคุณจะยังคงอยู่ที่นั่นเพียงเพื่อคุณจะไม่เห็นมันเป็น
Sisir

คำตอบ:


11

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

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

Eric Lippert ได้เขียนบทความสองสามข้อความเกี่ยวกับคำเตือนที่คุณจะพบข้อมูลเกี่ยวกับวิธีที่ทีมคอมไพเลอร์คิดเกี่ยวกับคำเตือน

เขตข้อมูลภายในของประเภทภายใน

การใช้คำสั่งที่ไม่ได้ใช้จะไม่ถูกทำเครื่องหมายด้วยคำเตือน


10

ต่อไปนี้เป็นคำเตือนบางประการที่เอกสารให้เหตุผลว่าทำไมคุณอาจต้องการปิดใช้งาน:

ตัวอย่างอื่น ๆ รวมถึงคำเตือนเกี่ยวกับการใช้วิธีการคิดค่าเสื่อมราคาหากคุณรู้ว่าคุณยังคงต้องการใช้วิธีการเก่าหรือมีสมาชิกส่วนตัวที่ไม่เคยอ่านในท้องถิ่น แต่มีการสะท้อนแทน

จากประสบการณ์ของฉัน C # มีความต้องการการปิดใช้งานคำเตือนน้อยกว่าภาษาอื่นเช่น C ++ นี่เป็นสาเหตุส่วนใหญ่เพราะอย่างที่ Eric Lippert กล่าวไว้ในบล็อกของเขาพวกเขา "พยายามจองคำเตือนเฉพาะสถานการณ์ที่เราสามารถพูดได้ด้วยความมั่นใจเกือบว่ารหัสนั้นถูกทำลายทำให้เข้าใจผิดหรือไร้ประโยชน์"


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

ฉันได้ทำการเขียนโปรแกรมแมโครจำนวนมากใน excel และฉันต้องปิดการใช้งานคำเตือนด้วยเหตุผลต่าง ๆ เช่นบันทึกอัตโนมัติ, ออกจากระบบอัตโนมัติ, การแจ้งเตือน ฯลฯ แน่นอนคุณอาจไม่ได้สนใจคำเตือนเหล่านี้ ...
Dave Mess

@ICR ฉันจำไม่ได้ว่าปิดการใช้งานคำเตือนคอมไพเลอร์ใน Java เลย สิ่งที่ฉันทำคือหลีกเลี่ยงการใช้วิธีการที่เลิกใช้แล้ว
Mahmoud Hossam

@Mahmoud ฉันมักจะพบว่าตัวเองต้องกด "ไม่ จำกัด " คำเตือนเมื่อทำอะไรที่ซับซ้อนได้จากระยะไกลด้วยยาชื่อสามัญ แต่มันอาจจะไม่ยุติธรรมที่จะปั้น Java ด้วย C ++ บนคำเตือนที่ไร้สาระ - แก้ไขคำตอบของฉัน
ICR

@ICR Java บังคับให้ใช้ generics เพื่อให้ความปลอดภัยในคอลเล็กชั่นในขณะที่บางคนมองว่าเป็นข้อ จำกัด ฉันคิดว่ามันเป็นคุณสมบัติมันทำให้การเขียนโค้ดค่อนข้างเจ็บปวด แต่ช่วยชีวิตและเอาท์พุทคอมไพเลอร์ C ++ ค่อนข้างน่ากลัวเมื่อพูดถึง STL หรืออะไรก็ตามที่มีเทมเพลต
Mahmoud Hossam

8

ตัวอย่างใน C ที่ฉันพบตัวแปรของประจำ:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

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

การแปลงคำเตือนไปสู่ข้อผิดพลาดค่อนข้างต้องใช้ช่องทางหนีสำหรับ "ไม่ใช่อันนี้ฉันรู้ดีกว่าคอมไพเลอร์ในกรณีนี้"


6

ห้องสมุด Java ที่ขาดไม่ได้หลายแห่งไม่เคยได้รับการอัพเดตเพื่อกำจัดความต้องการ typecasts ที่ไม่ปลอดภัย การระงับคำเตือนเหล่านั้นเป็นสิ่งที่จำเป็นเพื่อให้คำเตือนที่สำคัญอื่น ๆ จะได้รับการสังเกตและแก้ไข


5

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

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


3

มีเหตุผลเล็กน้อยที่จะปิดใช้งานการแจ้งเตือนคอมไพเลอร์แม้ในโครงการที่มุ่งมั่นเพื่อการปฏิบัติที่ดีที่สุด

  • คอมไพเลอร์ต่าง ๆ(หรือคอมไพเลอร์รุ่นเดียวกัน) :
    คอมไพเลอร์จัดการกับคำเตือนด้วยวิธีที่ต่างกันอย่างละเอียด ให้การเตือนที่ผิดพลาดโดยไม่ส่งผลกระทบต่อคอมไพเลอร์อื่น ๆ ในกรณีนี้อาจเหมาะสมที่จะปิดการใช้งานคำเตือนสำหรับคอมไพเลอร์เหล่านั้นแทนที่จะแก้ไขรหัสที่ถูกต้องเพื่อปิดเสียงเตือนที่เป็นเท็จซึ่งส่งผลกระทบต่อคอมไพเลอร์บางตัวเท่านั้นโดยเฉพาะอย่างยิ่งสำหรับคอมไพเลอร์รุ่นเก่า
  • ด้วยรหัสที่สร้างขึ้น:
    คำเตือนบางอย่างที่เกี่ยวข้องกับสุขอนามัยของรหัส (รหัสตาย, เนื้อความที่ซ้ำกันของข้อความแสดงเงื่อนไข, การเปรียบเทียบที่เกินขีด จำกัด ประเภท) สามารถละเว้นได้อย่างปลอดภัยเนื่องจากไม่มีอันตรายและคอมไพเลอร์จะปรับให้เหมาะสม
    การสร้างรหัสที่ไม่เพิ่มคำเตือนที่ไม่เป็นอันตรายเหล่านี้ก็เป็นทางเลือกเช่นกัน แต่อาจมีปัญหามากกว่านั้นคือความคุ้มค่า
  • คำเตือนสำหรับรหัสภายนอก:
    บางทีคุณอาจใช้การตรวจสอบ qsort หรือ md5 ที่รู้จักกันดีซึ่งรวมอยู่ในโครงการของคุณ รหัสถูกใช้ในหลาย ๆ โปรเจ็กต์และทำงานได้ดี แต่อาจมีคำเตือนที่พิถีพิถันซึ่งปกติแล้วคุณจะถูกต้องสำหรับโค้ดของคุณเอง
    รหัสภายนอก แต่มันอาจจะยุ่งยากน้อยที่จะปิดการใช้งานเพียงแค่เตือน (สมมติว่ามันแน่นอนเป็นอันตราย)
  • คำเตือนที่เกิดจากส่วนหัวของระบบ:
    แม้ว่า GCC / เสียงดังกราวสำหรับการสนับสนุนเช่น-isystemมีกรณีเมื่อความแตกต่างในส่วนหัวของระบบทำให้เกิดคำเตือนที่สามารถละเว้น (บางทีอาจจะเป็นฟังก์ชั่นที่มีค่าตอบแทนลงนามในระบบใดระบบหนึ่ง แต่ไม่อื่น) เรียก-Wsign-compareคำเตือน
    อีกกรณีหนึ่งอาจเป็นมาโครที่กำหนดไว้ในส่วนหัวของระบบคุณสามารถคัดลอกมาโครลงในรหัสของคุณเองเพื่อปรับเปลี่ยน แต่ทุกอย่างถือว่าดีกว่าไม่ต้องกังวลเกี่ยวกับการบำรุงรักษามาโครจากห้องสมุดของบุคคลที่สาม ... เพื่อปิดเสียงเตือน (อาจเป็นเพราะแมโครคิดถึงสาเหตุของการร่าย-Wsign-conversion)
  • คำเตือนที่ไม่ได้ใช้ในรหัสต้นขั้ว:
    คุณอาจเตือนถึงพารามิเตอร์ที่ไม่ได้ใช้อย่างไรก็ตามเมื่อทำการไลบรารี่ไลบรารีทั้งหมดในไฟล์เดียวที่มีฟังก์ชั่นสตับเท่านั้นมันไม่เป็นประโยชน์ในการบังคับ(void)arg1; (void)arg2; (void)arg3; ...ในเนื้อหาของทุกฟังก์ชันของต้นขั้ว
    ดีกว่าเพียงแค่ระงับ-Wunused-parameterในกรณีนี้

ทราบว่าในตัวอย่างทั้งหมดเหล่านี้มันถือว่าปิดการใช้งานคำเตือนไม่ได้ไปซ่อนข้อบกพร่องจริงเช่น: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotionบางที-Wpedantic... และที่คุณรู้ว่าสิ่งที่คุณกำลังทำอะไร!


2

ถูกต้องหรือไม่บางครั้งก็ทำเพื่อข้ามคำสั่ง "ถือว่าคำเตือนเป็นข้อผิดพลาด" บนเซิร์ฟเวอร์สร้าง

นอกเหนือจากนั้นฉันไม่สามารถคิดอย่างใดอย่างหนึ่ง คำเตือนที่ปิดใช้งานมักจะเป็นสัญญาณของ "hax น่าเกลียด" ...


2

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

ในระหว่างนี้เราจำเป็นต้องรวบรวมและเราต้องการตัวเลือก "คำเตือนเป็นข้อผิดพลาด" ในดังนั้นเราจึงระงับบางคำเตือน


2

ปัจจุบันคำเตือนเดียวที่ฉันไม่สนใจคือ

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

เนื่องจากไมโครซอฟท์ไม่ได้ใช้ข้อกำหนด C ++ (เอกสารยังระบุว่าไม่ได้!) และอนุญาตให้ฟังก์ชั่นประกาศการโยนที่เฉพาะเจาะจงและฟังก์ชั่นทั้งหมดสามารถโยนการโยน () หรือการโยน (... ) นั่นคือไม่มีอะไรเลย

จาก HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.