จะระงับคำเตือน GCC จากส่วนหัวของห้องสมุดได้อย่างไร


127

ฉันมีโปรเจ็กต์ที่ใช้ไลบรารี log4cxx, boost และอื่น ๆ ที่ส่วนหัวสร้างคำเตือน (ซ้ำ ๆ ) มากมาย มีวิธีระงับคำเตือนจากไลบรารี (เช่น #include <some-header.h>) หรือรวมจากบางเส้นทางหรือไม่ ฉันต้องการใช้ -Wall และ / หรือ -Wextra ตามปกติในรหัสโครงการโดยไม่ปิดบังข้อมูลที่เกี่ยวข้อง ปัจจุบันฉันใช้ grep ในการสร้างผลลัพธ์ แต่ฉันต้องการสิ่งที่ดีกว่า

คำตอบ:


128

คุณอาจจะพยายามที่จะรวมส่วนหัวห้องสมุดใช้แทน-isystem -Iซึ่งจะทำให้เป็น "ส่วนหัวของระบบ" และ GCC จะไม่รายงานคำเตือนสำหรับพวกเขา


11
หากคุณกำลังพยายามทำสิ่งนี้ใน XCode ให้ติด - เส้นทางระบบลงใน "แฟล็ก C ++ อื่น ๆ " ของคุณใน "แฟล็กคอมไพเลอร์ที่กำหนดเอง" ในการตั้งค่าบิลด์เป้าหมายของคุณ
Matt Parkins

3
ข้อเสียที่เป็นไปได้อย่างหนึ่งคือในบางแพลตฟอร์ม g ++ จะรวมส่วนหัวของระบบโดยอัตโนมัติextern "C"ซึ่งนำไปสู่ข้อผิดพลาดแปลก ๆ เกี่ยวกับการเชื่อมโยง C หากคุณ#includeใช้ส่วนหัว C ++ ใน-isystemเส้นทาง
Tavian Barnes

1
+1 ช่วยฉันแก้ปัญหาเกี่ยวกับคำเตือนการเพิ่มที่น่ารำคาญstackoverflow.com/questions/35704753/warnings-from-boost
mrgloom

3
เหตุใดสิ่งนี้จึงมีคะแนนโหวตมากกว่าคำตอบของ OP ที่กล่าวว่าเหมือนกันทุกประการเมื่อ 1.5 ชั่วโมงก่อนหน้านี้
underscore_d

1
สำหรับ Xcode: จะเกิดอะไรขึ้นถ้าไม่มีเส้นทางโฟลเดอร์ใน "แฟล็ก C ++ อื่น ๆ " ในการตั้งค่าบิลด์เป้าหมายของฉัน มีใครสามารถอธิบายวิธีแก้ปัญหานี้อย่างละเอียดได้หรือไม่?
Ossir

108

สำหรับผู้ที่ใช้ CMake คุณสามารถแก้ไขinclude_directoriesคำสั่งของคุณเพื่อรวมสัญลักษณ์SYSTEMที่ระงับคำเตือนเกี่ยวกับส่วนหัวดังกล่าว

include_directories(SYSTEM "${LIB_DIR}/Include")
                    ^^^^^^

จะเกิดอะไรขึ้นถ้าไลบรารีมี${LIBFOO_USE_FILE}ตัวแปรที่จะใช้กับคำสั่งinclude ()ของ CMake ?
waldyrious

2
นี่ดูเหมือนจะเกือบจะเป็นทางออกสำหรับปัญหาของฉัน ฉันมี 1. ) เป้าหมายไบนารีซึ่งขึ้นอยู่กับ 2. ) ส่วนหัวเท่านั้นที่เป็นเป้าหมายที่เขียนขึ้นเองซึ่งขึ้นอยู่กับ 3. ) ไลบรารีภายนอกบางส่วน ฉันไม่รู้ว่าจะรับคำเตือนสำหรับ 1 & 2 ได้อย่างไร คุณมีความคิดใด ๆ ?
knedlsepp

2
ดูเหมือนจะไม่ทำงาน ฉันลองสิ่งนี้กับโปรเจ็กต์ที่ใช้easylogging++และฉันได้รับคำเตือนจำนวนมากเหมือนกันจากeasylogging++.hแม้ว่าโฟลเดอร์ที่มันอยู่จะรวมอยู่ในSYSTEMตัวเลือกก็ตาม
rbaleksandar

ขอบคุณมากสำหรับสิ่งนี้ มันช่วยฉันจากหน้าและหน้าคำเตือน
Svalorzen

1
ความคิดเห็นเช่นเดียวกับคำตอบที่ยอมรับ: นี่เป็นการปฏิบัติที่ไม่ดีสำหรับฉัน
Raffi

55

คุณสามารถใช้ pragmas ตัวอย่างเช่น:

// save diagnostic state
#pragma GCC diagnostic push 

// turn off the specific warning. Can also use "-Wall"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"

#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>

// turn the warnings back on
#pragma GCC diagnostic pop

3
ใช้ได้เฉพาะกับ GCC> = 4.6
Caduchon

1
ฉันชอบความสามารถของ push / pop pragmas ฉันจำได้ว่ามีบางอย่างสำหรับ java เมื่อหลายปีก่อนและรู้สึกผิดหวัง / อิจฉา C / C ++ ฉันชอบที่สิ่งนี้มีอยู่ในgcc
Trevor Boyd Smith

@TrevorBoydSmith MS clมีความสามารถมาหลายปีแล้วด้วย ... บางครั้งgccก็ปรับตัวได้ช้านิดหน่อย
Alexis Wilke

29

เจอทีเด็ดแล้ว สำหรับไลบรารีประกอบด้วยแทนที่จะ-Idirใช้-isystem dirใน makefile จากนั้น GCC จะถือว่าการเพิ่มประสิทธิภาพเป็นต้นเนื่องจากระบบรวมและละเว้นคำเตือนใด ๆ จากพวกเขา


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

9

#pragmaเป็นคำแนะนำสำหรับคอมไพเลอร์ คุณสามารถตั้งค่าบางอย่างก่อน #include และปิดใช้งานหลังจากนั้น

นอกจากนี้คุณยังสามารถทำมันได้ในบรรทัดคำสั่ง

หน้า GCC อีกเฉพาะในคำเตือนการปิดใช้งาน

ฉันจะไปสำหรับตัวเลือกของการใช้ของ # pragma ภายในรหัสแหล่งที่มาและจากนั้นให้เป็น เสียงเหตุผล (เป็นความคิดเห็น) เหตุผลที่คุณจะปิดการใช้งานคำเตือน นี่หมายถึงการให้เหตุผลเกี่ยวกับไฟล์ส่วนหัว

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

หมายเหตุ: คุณยังสามารถนวดรหัสที่มาเพื่อป้องกันไม่ให้คำเตือนบางอย่างโดยใช้แอตทริบิวต์ ; อย่างไรก็ตามสิ่งนี้ผูกมัดคุณอย่างใกล้ชิดกับ GCC

หมายเหตุ 2: GCC ยังใช้อินเทอร์เฟซป๊อป / พุชตามที่ใช้ในคอมไพเลอร์ของไมโครซอฟท์ - Microsoft ปิดใช้งานคำเตือนผ่านอินเทอร์เฟซนี้ ฉันขอแนะนำให้คุณตรวจสอบเรื่องนี้เพิ่มเติมเนื่องจากฉันไม่ทราบว่าเป็นไปได้หรือไม่


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

4

คุณสามารถลองใช้ส่วนหัว precompiled คำเตือนจะไม่หายไป แต่อย่างน้อยก็จะไม่ปรากฏในการรวบรวมหลักของคุณ


1
นี่อาจเป็นความคิดที่ดี บุคคลที่สามรวมถึงอย่าเปลี่ยนทุกวัน
AdSR

เผง แม้ว่าฉันจะไม่ได้ใช้มันมากขนาดนั้นใน Linux แต่ก็ทำงานได้ดีบน Visual Studio
Pablo Santa Cruz

ไม่พวกเขาจะยังคงปรากฏในการคอมไพล์เว้นแต่คุณจะใช้วิธีอื่นในการระงับ (เช่น-isystemแต่อย่าลืมใช้ทั้งในการคอมไพล์ส่วนหัวและในโค้ด)
user202729

2

หากคุณต้องการลบล้างส่วนหัวของระบบอย่างชัดเจนคุณจะถูก จำกัด ไว้ที่ pragmas คุณสามารถตรวจสอบได้ว่าคุณกำลังใช้งานใดผ่านmake dependเอาต์พุต

โปรดดูpush-pop สำหรับการวินิจฉัยสำหรับ gcc> = 4.6


1

วางสิ่งต่อไปนี้

#pragma GCC system_header

จะปิดคำเตือน GCC สำหรับโค้ดต่อไปนี้ทั้งหมดในไฟล์นี้


-9

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


+1 สำหรับคำแนะนำที่ดี: D แต่เขากำลังถามวิธีการทำบางอย่างที่เฉพาะเจาะจง: D
Hassan Syed

4
คำเตือนบางอย่างเป็นไปไม่ได้หรือแก้ไขได้ยากมากโดยเฉพาะอย่างยิ่งในโค้ดของบุคคลที่สามโดยเฉพาะอย่างยิ่งในโค้ดที่มีการเขียนโปรแกรม metaprogramming เช่น Boost
ulidtko

3
ที่แย่กว่านั้นคือ"การประกาศ" c "เงามืดสมาชิกของ" this "[-Werror = shadow]"ลึกลงไปในส่วนหัวของการเพิ่มพลัง นั่นไม่ใช่ปัญหาอย่างแน่นอน แต่ปัญหาที่คล้ายกันคือการพ่นเอาต์พุตและทำให้ยากสำหรับฉันที่จะพบว่าอินสแตนซ์เป็นเงาที่แท้จริงในฐานรหัสของเรา
dmckee --- อดีตผู้ดูแลลูกแมว
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.