ปิดการใช้งานคำเตือน GCC เฉพาะบางส่วนของหน่วยการแปลหรือไม่


85

GCC ที่ใกล้เคียงที่สุดเทียบเท่ากับรหัสตัวประมวลผลล่วงหน้า MSVC นี้คืออะไร

#pragma warning( push )                    // Save the current warning state.
#pragma warning( disable : 4723 )          // C4723: potential divide by 0
// Code which would generate warning 4723.
#pragma warning( pop )                     // Restore warnings to previous state.

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


หากมีการติดตั้งส่วนหัวไปที่ / usr / include หรือสิ่งที่คุณมี gcc จะไม่สร้างคำเตือนให้ตามค่าเริ่มต้น
Spudd86

คำตอบ:


95

สิ่งนี้เป็นไปได้ใน GCCตั้งแต่เวอร์ชัน 4.6 หรือประมาณเดือนมิถุนายน 2010 ในลำต้น

นี่คือตัวอย่าง:

#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

8
เพิ่มฟังก์ชันพุชและป๊อปใน gcc 4.6 ( gcc.gnu.org/onlinedocs/gcc-4.6.0/gcc/Diagnostic-Pragmas.html )
Dave Johansen

1
คุณอาจต้องการผลักดันสองครั้งหากคุณจะป๊อปสองครั้ง
แดน

2
@ แดน: อ่านคู่มือและแสดงความคิดเห็น สังเกตที่มาของตัวอย่าง
Matt Joiner

FYI สำหรับเวอร์ชันเก่าเช่น 4.4.7คุณยังสามารถใช้งานได้#pragma GCC diagnostic [error|warning|ignored]แต่popไม่ได้ใช้งาน / รองรับ
Trevor Boyd Smith

36

สิ่งที่ใกล้เคียงเป็นGCC pragma วินิจฉัย#pragma GCC diagnostic [warning|error|ignored] "-Wwhatever" , ไม่ได้อยู่ใกล้กับสิ่งที่คุณต้องการมากนักโปรดดูรายละเอียดและข้อควรระวังในลิงก์


1
คุณรู้หรือไม่ว่าเหตุผลในการไม่เพิ่มคุณสมบัตินี้คืออะไรและที่ไหน? (หาไม่เจอ) ฉันพบว่าคำเตือน push-disable-pop มีประโยชน์

1
ฉันนึกภาพไม่ออกจริงๆว่าการ "ไม่เพิ่มฟีเจอร์" ให้กับ gcc มักจะมีเหตุผลมากพอ ๆ กับที่ไม่มีใครส่งแพตช์ที่ใช้งานได้
ความโกลาหล

14
ไม่ใช่ว่าไม่มีใครเต็มใจที่จะทำงานสำหรับการควบคุมคำเตือนแบบละเอียดใน gcc หรือส่งรหัส - ฉันรู้จัก บริษัท ซิลิคอนวัลเลย์รายใหญ่แห่งหนึ่งที่ทำสิ่งนี้ไปแล้วและอีก บริษัท หนึ่งที่ยินดีที่จะจ่ายเงินให้ใครสักคน ที่จะทำและรับรหัสในสตรีม แต่ตามการสนทนากับผู้ชายที่ (ในฐานะผู้ดูแลระบบ gdb คนหนึ่ง) เสียบเข้ากับสิ่งนี้ผู้ดูแลระบบ gcc มีปรัชญาว่า "หากมีคำเตือนแสดงว่าเป็นข้อบกพร่องและคุณต้องแก้ไข" ดังนั้น (imo) จึงเป็นข้อโต้แย้งทางศาสนาและพวกเขาควบคุมรหัสเพื่อให้พวกเขาชนะ
Bob Murphy

เพื่อเพิ่มความคิดเห็นของ Bob นักพัฒนา GCC มีประวัติไม่ชอบ#pragmaคำสั่งดังนั้นสิ่งใดก็ตามที่เฉพาะ GCC จึงมีแนวโน้มที่จะนำไปใช้เป็น__attribute__((foo))ไฟล์.
ทอม

10
gcc ใหม่ (> = 4.4) มี#pragma GCC push_optionsมากกว่าการวินิจฉัย ... gcc.gnu.org/onlinedocs/gcc/…
Spudd86

33

ฉันได้ทำสิ่งที่คล้ายกัน สำหรับรหัสของบุคคลที่สามฉันไม่ต้องการเห็นคำเตือนใด ๆ เลย ดังนั้นแทนที่จะระบุผมใช้-I/path/to/libfoo/include -isystem /path/to/libfoo/includeสิ่งนี้ทำให้คอมไพเลอร์ถือว่าไฟล์ส่วนหัวเหล่านั้นเป็น "ส่วนหัวของระบบ" เพื่อจุดประสงค์ในการเตือนและตราบใดที่คุณไม่ได้เปิดใช้งาน-Wsystem-headersงานคุณก็ปลอดภัยเป็นส่วนใหญ่ ฉันยังคงเห็นคำเตือนบางอย่างรั่วไหลออกมา แต่มันช่วยลดขยะส่วนใหญ่ได้

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


1
เคล็ดลับที่ดี หากใช้ LLVM ให้เพิ่มแฟล็ก -isystem ใน "Other C Flags" ในส่วน "Apple LLVM Compiler - Language"
Nestor

@Tom ขอบคุณสำหรับการแบ่งปัน ฉันไม่เข้าใจว่าจะใช้โซลูชันของคุณที่ไหน คุณช่วยพูดอีกนิดได้ไหม
ลอเรนโซบี

1

นี้คือการขยายตัวไปยังคำตอบที่แมตต์ช่างไม้ของ

หากคุณไม่ต้องการวางไข่บนรหัสของคุณคุณสามารถใช้ตัวดำเนินการ _Pragma :

#ifdef __GNUC__
#  define DIAGNOSTIC_ERROR(w) _Pragma("GCC diagnostic error \"" w "\"")
#  define DIAGNOSTIC_IGNORE(w) _Pragma("GCC diagnostic ignore \"" w "\"")
#  define DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
#  define DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
#endif
// (...)

DIAGNOSTIC_ERROR("-Wuninitialized")
foo(a); // Error

DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE("-Wuninitialized")
foo(a); // No error

DIAGNOSTIC_POP
foo(a); // Error
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.