禁用单个警告错误


114

有没有办法用Visual Studio禁用cpp文件中的单个警告行?

例如,如果我捕获一个异常但不处理它,则会收到错误4101(未引用的局部变量)。有没有一种方法可以仅在该函数中忽略它,否则可以在编译单元中报告它?此刻,我将#pragma warning (disable : 4101)文件放在顶部,但是很明显,整个文件都将其关闭。


19
如果仅提及类型而未命名例外,则不会发出警告。例如catch (const std::exception& /* unnamed */) {.... }。它不能回答您的问题,但可以解决您的问题。
Sjoerd

Answers:


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

1
@Cookie:是的,它适用于通过编译器的任何代码段。
Matteo Italia

有关最新的简洁答案,请参见下面的丹尼尔·索斯的答案。
Dan Nissenbaum

4
clang似乎不支持这种编译,但你可以实现与同样的效果#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wunused-variable"#pragma clang diagnostic pop。请参见“控制Diagnositics公司通过编译指示”,在锵用户手册
风铃草

由于我很少使用此功能,因此当我这样做时,通常会在此页面结束以提醒自己语法。我只是把它放在对一个可能永远不会更新的不推荐使用的函数的调用周围,这样警告就不会在编译器列表中烦扰我,我认真地进行了扫描。
David A. Gray

对于Visual Studio,命令行参数为/wd4101。请注意:,标志和数字之间不是正常的,并且您不能用逗号分隔数字列表。对于其他编译器,可能/nowarn:4101改为。
Jesse Chisholm

89

如果只想在一行代码中禁止显示警告,则可以使用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'3

2
@MarkoPopovic:该suppress说明符在经过预处理的一行代码上运行。如果下面的行#pragma warning(suppress: ...)#include指令(它将其参数引用的文件扩展到当前编译单元中),则该效果仅适用于该文件的第一行。这应该是显而易见的,因为警告是由编译器生成的。编译器对预处理的代码进行操作。
IInspectable,2013年

@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)。
Matteo Italia

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)

此编译指示对于从Visual Studio 2005开始的C ++有效。
。https: v= .aspx

该杂项对于通过Visual Studio 2005到Visual Studio 2015的C#无效。
错误:“预期禁用或还原”。
(我想他们永远都无法实现suppress...)https://msdn.microsoft.com/zh-cn/library/441722ys(v=vs.140 )
.aspx

C#需要不同的格式。它看起来像这样(但不起作用):

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

相反的suppress,你要disableenable

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调试版本相同的功能,而P=P在发行版本中使用相同的功能。

#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:我认为(void)unusedVar;?不符合C ++标准。
2011年

2
它是一个表达式,其值不为空。在C ++中,您甚至可以这样做static_cast<void>(unusedVar)
Nawaz

2
@纳瓦兹 赫伯·萨特(Herb Sutter)的解释:herbutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings
阿列克谢·

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上遇到过这种情况,当仅在decltype语句中使用'e'时,编译器会抱怨,但您必须具有命名的varible e

以上所有非#pragma建议都归结为仅添加一条语句:

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

1
现在(在MS VS2015编译器中),这将导致C4702无法访问代码
Cee McSharpface

2

如@rampion所述,如果您使用的是clang gcc,则警告是按名称而不是数字进行的,您需要执行以下操作:

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

此信息来自这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.