【问题标题】:Disable single warning error禁用单个警告错误
【发布时间】:2011-11-01 19:51:23
【问题描述】:

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

例如,如果我捕获一个异常但不处理它,我会收到错误 4101(未引用的局部变量)。有没有办法在那个函数中忽略它,但在编译单元中报告它?目前,我将#pragma warning (disable : 4101) 放在文件的顶部,但这显然只是将整个单元关闭。

【问题讨论】:

  • 如果只提及类型而不命名异常,则不会出现警告。例如。 catch (const std::exception& /* unnamed */) {.... }。它不能回答您的问题,但可能会解决您的问题。
  • Google 在此处搜索 "how to suppress -Wunused-result in c++" 导致,所以这里是针对特定情况的答案:stackoverflow.com/a/63512122/4561887

标签: c++ visual-c++ warnings pragma


【解决方案1】:
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 

【讨论】:

  • @Cookie:是的,它适用于通过编译器的任何代码。
  • 有关更新的简明答案,请参阅下面 Daniel Seither 的答案。
  • clang 似乎不支持此编译指示,但您可以使用#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wunused-variable"#pragma clang diagnostic pop 实现相同的效果。见"Controlling Diagnositics Via Pragmas" in the Clang User's Manual
  • 由于我不经常使用此功能,所以当我这样做时,我通常会在此页面上结束以提醒自己语法。我只是将它放在对可能永远不会更新的已弃用函数的调用周围,这样警告就不会在编译器列表中惹恼我,我会认真扫描。
  • 对于 Visual Studio,命令行参数是 /wd4101。请注意,标志和数字之间没有正常的:,您不能使用逗号分隔的数字列表。对于其他编译器,它可能改为/nowarn:4101
【解决方案2】:

如果您只想在一行代码中抑制警告(预处理后)[1],您可以使用suppresswarning specifier

#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)

[1] 其他人在下面的 cmets 中指出,如果以下语句是 #include 语句,则 #pragma warning(suppress: 4101) 语句不会有效地抑制头文件中每一行的警告。如果打算这样做,则需要使用 push/disable/pop 方法。

【讨论】:

  • 非常有用!不幸的是,它不适用于包含生成警告的标题的单行。
  • @MarkoPopovic:suppress 说明符在单个预处理代码行上运行。如果#pragma warning(suppress: ...) 之后的行是#include 指令(将其参数引用的文件扩展为当前编译单元),则效果仅适用于该文件的第一行。这应该很明显,因为警告是由编译器生成的。编译器对预处理代码进行操作。
  • @IInspectable 在这种情况下,我将其称为 后处理 行代码。 pre-processed 表示它还没有被预处理器翻译。
  • @voi:"-ed" 结尾表示past participle。它用于表示过去某事已经结束。 “预处理” 行是已完全处理的行。
  • 这些 cmets 让我有点困惑,如果有人陷入同一条船上,他们的意思是 #pragma warning(suppress: 4101) \n #include "wholeFile.h 不会抑制整个标题中的错误(显然,但 cmets 通常指向不明显的行为,因此造成混乱)您可以在标题本身中使用它没有问题
【解决方案3】:

#pragmapush/pop 往往是这类问题的解决方案,但是这种情况下为什么不直接删除未引用的变量呢?

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

【讨论】:

  • 这不是问题的答案。诚然,这可能会解决 OP 的问题,但不会帮助未来的读者解决一个类似的问题:“如何关闭代码特定部分的特定警告?”
  • @Sjoerd:三个人已经回答了其他人可能会搜索的“官方问题”,所以我尝试在字里行间阅读并解决他的实际问题(在您发表评论后一分钟到达:P )。
  • @Sjoerd 作为未来的读者,我证明这个答案确实对我有所帮助。
  • @Mołot:作为过去的作家,我很高兴它有所帮助。 =)
  • 10 年后,我仍然没有使用异常......我经常使用 (cl.exe) /kernel 开关进行编译。
【解决方案4】:

使用#pragma warning ( push ),然后#pragma warning ( disable ),然后输入您的代码,然后使用#pragma warning ( pop ),如here所述:

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

【讨论】:

    【解决方案5】:

    例子:

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

    此编译指示适用于从 Visual Studio 2005 开始的 C++
    https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

    编译指示不适用于 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)
    

    您必须使用disableenable,而不是suppress

    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
    

    【讨论】:

      【解决方案6】:

      正如@rampion 提到的,如果您在 clang gcc 中,警告是按名称而不是编号,您需要这样做:

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

      此信息来自here

      【讨论】:

        【解决方案7】:

        不要把它放在文件(甚至是头文件)的顶部,只需用#pragma warning (push)#pragma warning (disable) 和匹配的#pragma warning (pop) 包装有问题的代码,如图所示here

        虽然还有一些其他选项,包括#pramga warning (once)

        【讨论】:

          【解决方案8】:

          也可以使用WinNT.H 中定义的UNREFERENCED_PARAMETER。定义只是:

          #define UNREFERENCED_PARAMETER(P)          (P)
          

          并像这样使用它:

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

          你为什么要使用它,你可能会争辩说你可以省略变量名本身。好吧,在某些情况下(不同的项目配置,调试/发布版本)可能会实际使用该变量。在另一种配置中,该变量未使用(因此出现警告)。

          某些静态代码分析可能仍会针对这种无意义的声明 (wParam;) 发出警告。在这种情况下,您可以在调试版本中使用与UNREFERENCED_PARAMETER 相同的DBG_UNREFERENCED_PARAMETER,在发布版本中使用P=P

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

          【讨论】:

          • 请注意,从 C++11 开始,我们有 [[maybe_unused]] 属性
          【解决方案9】:

          如果你想禁用unreferenced local variable 写一些标题

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

          并使用

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

          【讨论】:

          • 一个函数调用,只是为了抑制警告?你为什么不这样做呢:(void)unusedVar;?
          • @Nawaz:我认为(void)unusedVar;?不符合 C++ 标准。
          • 它是一个值为零的表达式。在 C++ 中,您甚至可以使用 static_cast&lt;void&gt;(unusedVar)
          • §5.2.9/4 说,Any expression can be explicitly converted to type “cv void.” The expression value is discarded 根据它你可以写 static_cast&lt;void&gt;(unusedVar)static_cast&lt;const void&gt;(unusedVar)static_cast&lt;volatile void&gt;(unusedVar)。所有表格均有效。我希望它能澄清你的疑问。
          【解决方案10】:

          在某些情况下,您必须有一个命名参数,但不能直接使用它。
          例如,我在 VS2010 上遇到过,当 'e' 仅在 decltype 语句中使用时,编译器会报错,但您必须拥有命名变量 e

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

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

          【讨论】:

          • 现在(在 MS VS2015 编译器中)这会导致 C4702 无法访问代码
          【解决方案11】:

          这个问题是 Google search for "how to suppress -Wunused-result in c++" 的前 3 个热门问题之一,所以我在这里添加这个答案,因为我想通了并想帮助下一个人。

          如果您的警告/错误是-Wunused(或其子错误之一)或-Wunused -Werror,解决方案是转换为void

          对于-Wunused 或其子错误之一1,您只需将其转换为void 即可禁用警告。这应该适用于 C 和 C++ 的任何编译器和任何 IDE。

          1注意 1:请参阅此处的 gcc 文档,例如,有关这些警告的列表:https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html,然后搜索短语“所有上述 -Wunused 选项组合”并查看那里对于主要的-Wunused 警告,在其上方是其子警告。 -Wunused 包含的子警告包括:

          • -Wunused-but-set-parameter
          • -Wunused-but-set-variable
          • -Wunused-function
          • -Wunused-label
          • -Wunused-local-typedefs
          • -Wunused-parameter
          • -Wno-unused-result
          • -Wunused-variable
          • -Wunused-const-variable
          • -Wunused-const-variable=n
          • -Wunused-value
          • -Wunused = 包含上述所有-Wunused 选项组合

          强制转换为 void 以抑制此警告的示例:

          // some "unused" variable you want to keep around
          int some_var = 7;
          // turn off `-Wunused` compiler warning for this one variable
          // by casting it to void
          (void)some_var;  // <===== SOLUTION! ======
          

          对于 C++,这也适用于返回标有 [[nodiscard]] 的变量的函数:

          C++ 属性:nodiscard(C++17 起)
          如果一个声明为 nodiscard 的函数或一个返回枚举的函数或按值声明为 nodiscard 的类从一个废弃值表达式调用而不是强制转换为 void,则鼓励编译器发出警告。
          (来源:https://en.cppreference.com/w/cpp/language/attributes/nodiscard

          因此,解决方案是将函数调用转换为void,因为这实际上是将函数返回的值(标有[[nodiscard]] 属性)转换为@987654351 @。

          例子:

          // Some class or struct marked with the C++ `[[nodiscard]]` attribute
          class [[nodiscard]] MyNodiscardClass 
          {
          public:
              // fill in class details here
          private:
              // fill in class details here
          };
          
          // Some function which returns a variable previously marked with
          // with the C++ `[[nodiscard]]` attribute
          MyNodiscardClass MyFunc()
          {
              MyNodiscardClass myNodiscardClass;
              return myNodiscardClass;
          }
          
          int main(int argc, char *argv[])
          {
              // THE COMPILER WILL COMPLAIN ABOUT THIS FUNCTION CALL
              // IF YOU HAVE `-Wunused` turned on, since you are 
              // discarding a "nodiscard" return type by calling this
              // function and not using its returned value!
              MyFunc();
          
              // This is ok, however, as casing the returned value to
              // `void` suppresses this `-Wunused` warning!
              (void)MyFunc();  // <===== SOLUTION! ======
          }
          

          最后,您还可以使用 C++17 [[maybe_unused]] 属性:https://en.cppreference.com/w/cpp/language/attributes/maybe_unused

          【讨论】:

            猜你喜欢
            • 2013-04-24
            • 2012-10-06
            • 2013-03-11
            • 2014-03-31
            • 1970-01-01
            • 1970-01-01
            • 2022-12-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多