ปิดใช้งานข้อผิดพลาดคำเตือนเดียว


115

มีวิธีปิดการใช้งานคำเตือนเพียงบรรทัดเดียวในไฟล์ cpp ด้วย visual studio หรือไม่?

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


19
หากคุณพูดถึงเฉพาะประเภทและไม่ตั้งชื่อข้อยกเว้นจะไม่มีคำเตือน เช่นcatch (const std::exception& /* unnamed */) {.... }. ไม่ตอบคำถามของคุณ แต่อาจช่วยแก้ปัญหาของคุณได้
Sjoerd

คำตอบ:


182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 

1
@ คุกกี้: ใช่มันใช้งานได้กับโค้ดใด ๆ ที่ผ่านคอมไพเลอร์
Matteo Italia

สำหรับคำตอบล่าสุดที่กระชับดูคำตอบของ Daniel Seither ด้านล่าง
Dan Nissenbaum

4
clangดูเหมือนจะไม่สนับสนุน pragma นี้ แต่คุณสามารถบรรลุผลเช่นเดียวกันกับ#pragma clang diagnostic push, และ#pragma clang diagnostic ignored "-Wunused-variable" #pragma clang diagnostic popดู"การควบคุมการวินิจฉัยผ่าน Pragmas" ในคู่มือผู้ใช้เสียงดัง
rampion

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

สำหรับ Visual Studio /wd4101อาร์กิวเมนต์บรรทัดคำสั่ง โปรดสังเกตว่า:แฟล็กและตัวเลขไม่ใช่เรื่องปกติและคุณไม่สามารถทำรายการตัวเลขที่คั่นด้วยจุลภาคได้ สำหรับคอมไพเลอร์อื่นอาจเป็น/nowarn:4101แทน
Jesse Chisholm

90

หากคุณต้องการระงับคำเตือนในโค้ดบรรทัดเดียวเท่านั้นคุณสามารถใช้ตัวsuppress ระบุคำเตือน :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

สำหรับโค้ดบรรทัดเดียวการดำเนินการนี้จะเหมือนกับการเขียนข้อความต่อไปนี้:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)

8
มีประโยชน์มาก! ขออภัยมันใช้ไม่ได้กับบรรทัดเดียวที่มีส่วนหัวที่สร้างคำเตือน
Marko Popovic

2
@MarkoPopovic: ตัวsuppressระบุทำงานบนโค้ดบรรทัดเดียวที่ประมวลผลล่วงหน้า หากบรรทัดต่อไปนี้#pragma warning(suppress: ...)เป็น#includeคำสั่ง (ซึ่งขยายไฟล์ที่อ้างอิงโดยพารามิเตอร์ไปยังหน่วยคอมไพล์ปัจจุบัน) เอฟเฟกต์จะใช้กับบรรทัดแรกของไฟล์นั้นเท่านั้น สิ่งนี้ควรชัดเจนเนื่องจากคอมไพเลอร์สร้างคำเตือน คอมไพเลอร์ทำงานบนโค้ดก่อนประมวลผล
ระบุได้

@IInspectable ในกรณีนั้นฉันจะเรียกมันว่าบรรทัดรหัสหลังการประมวลผล ประมวลผลล่วงหน้าหมายความว่ายังไม่ได้แปลโดยตัวประมวลผลล่วงหน้า
void.pointer

2
@voi ที่: "-ed"สิ้นสุดหมายถึงกริยาที่ผ่านมา มันถูกใช้เพื่อแสดงว่าบางสิ่งบางอย่างได้จบลงแล้วในอดีต "ก่อนการประมวลผล"สายเป็นสายที่ได้รับการดำเนินการอย่างเต็มที่
IInspectable

29

#pragma push / pop มักจะเป็นทางออกสำหรับปัญหาประเภทนี้ แต่ในกรณีนี้ทำไมคุณไม่ลบตัวแปรที่ไม่ได้อ้างอิงออกไปล่ะ

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}

6
นี่ไม่ใช่การตอบคำถาม จริงอยู่สิ่งนี้อาจช่วยแก้ปัญหาของ OP ได้ แต่จะไม่ช่วยผู้อ่านในอนาคตด้วยคำถามจำลอง: "ฉันจะปิดคำเตือนเฉพาะบางส่วนของโค้ดของฉันได้อย่างไร"
Sjoerd

1
@Sjoerd: คนสามคนตอบ "คำถามอย่างเป็นทางการ" ที่คนอื่นอาจค้นหาแล้วดังนั้นฉันจึงพยายามอ่านระหว่างบรรทัดและแก้ปัญหาที่แท้จริงของเขาแทน (มาถึงหนึ่งนาทีหลังจากความคิดเห็นของคุณ:P)
มัตเตโออิตาเลีย

11
@Sjoerd ในฐานะผู้อ่านในอนาคตฉันยืนยันว่าคำตอบนี้ช่วยฉันได้จริง
Mołot

2
@ Mołot: ในฐานะนักเขียนที่ผ่านมาฉันดีใจที่มีส่วนช่วย =)
Matteo Italia

9

ใช้#pragma warning ( push )จาก#pragma warning ( disable )นั้นใส่รหัสของคุณจากนั้นใช้#pragma warning ( pop )ตามที่อธิบายไว้ที่นี่ :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 

8

ตัวอย่าง:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

pragma นี้ใช้ได้สำหรับC ++ ที่เริ่มต้นด้วย Visual Studio 2005
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

pragma ไม่ถูกต้องสำหรับC #ผ่าน Visual Studio 2005 ผ่าน Visual Studio 2015
ข้อผิดพลาด: "คาดว่าจะปิดใช้งานหรือกู้คืน"
(ฉันเดาว่าพวกเขาไม่เคยใช้งานsuppress... )
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # ต้องการรูปแบบอื่น จะมีลักษณะดังนี้ (แต่ใช้ไม่ได้):

#pragma warning suppress 0642  // (suppress one error in the next line)

แทนที่จะเป็นเช่นsuppressนั้นคุณต้องdisableและenable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

มันน่าเกลียดมากฉันคิดว่ามันฉลาดกว่าที่จะจัดสไตล์ใหม่:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else

5

แทนที่จะวางไว้ที่ด้านบนของไฟล์ (หรือแม้กระทั่งไฟล์ส่วนหัว) เพียงห่อรหัสในคำถามด้วย#pragma warning (push), #pragma warning (disable)และการจับคู่#pragma warning (pop)ที่แสดงที่นี่ที่นี่

แม้ว่าจะมีตัวเลือกอื่น ๆ ได้แก่#pramga warning (once).


5

อาจใช้ที่UNREFERENCED_PARAMETERกำหนดไว้ในWinNT.H. คำจำกัดความเป็นเพียง:

#define UNREFERENCED_PARAMETER(P)          (P)

และใช้มันเช่น:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

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

การวิเคราะห์โค้ดแบบคงที่บางอย่างอาจยังคงให้คำเตือนสำหรับคำสั่งที่ไม่ใช่เรื่องไร้สาระนี้ ( wParam;) ในกรณีนั้นคุณอาจใช้DBG_UNREFERENCED_PARAMETERสิ่งที่เหมือนกับUNREFERENCED_PARAMETERใน debug builds และทำP=Pใน release build

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)

1
โปรดทราบว่าตั้งแต่ C ++ 11 เรามี[[maybe_unused]]แอตทริบิวต์
metablaster

2

หากคุณต้องการปิดการunreferenced local variableเขียนในบางส่วนหัว

template<class T>
void ignore (const T & ) {}

และใช้

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 

2
การเรียกใช้ฟังก์ชันเพียงเพื่อระงับคำเตือน? ทำไมคุณไม่ทำสิ่งนี้แทน: (void)unusedVar;?
Nawaz

@Nawaz: ฉันคิดว่า(void)unusedVar;?ไม่เป็นไปตามมาตรฐาน C ++
Alexey Malistov

2
มันเป็นนิพจน์ที่ไม่มีค่าอะไรเลย ใน C ++ static_cast<void>(unusedVar)คุณยังสามารถทำ
Nawaz


2
§5.2.9 / 4 กล่าวAny expression can be explicitly converted to type “cv void.” The expression value is discardedตามที่คุณสามารถเขียนstatic_cast<void>(unusedVar)และstatic_cast<const void>(unusedVar)และstatic_cast<volatile void>(unusedVar). ทุกรูปแบบถูกต้อง ฉันหวังว่ามันจะกระจ่างข้อสงสัยของคุณ
Nawaz

2

ในบางสถานการณ์คุณต้องมีพารามิเตอร์ที่ตั้งชื่อ แต่ไม่ได้ใช้โดยตรง
ตัวอย่างเช่นฉันพบมันใน VS2010 เมื่อใช้ 'e' ภายในdecltypeคำสั่งเท่านั้นคอมไพเลอร์จะบ่น แต่คุณต้องมีชื่อตัวแปรevarible

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

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}

1
ตอนนี้ (ในคอมไพเลอร์ MS VS2015) ซึ่งทำให้เกิดรหัสที่ไม่สามารถเข้าถึง C4702
Cee McSharpface

2

ตามที่ @rampion กล่าวถึงหากคุณอยู่ในเสียงดัง gcc คำเตือนจะเป็นตามชื่อไม่ใช่ตัวเลขและคุณจะต้องทำ:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

ข้อมูลนี้มาจากที่นี่

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