代码之家  ›  专栏  ›  技术社区  ›  AnthonyWJones

在C中禁止“从未使用”和“从未分配给”警告#

  •  100
  • AnthonyWJones  · 技术社区  · 14 年前

    我在C项目中有一个httpsystemdefinitions.cs文件,它基本上描述了旧的Windows ISAPI,供托管代码使用。

    这包括与ISAPI相关的完整结构集,而不是全部或由代码使用。在编译时,这些结构的所有字段成员都会引发如下警告:

    警告字段“unionsquare.isapi.http_filter_prerc_headers.setheader”从未分配给,并且始终将其默认值为空。

    警告字段“unionsquare.isapi.http_filter_prerc_headers.httpstatus”从未使用

    这些能不能用 #pragma warning disable ?如果是,对应的错误号是什么?如果没有,我还能做什么?记住,我只需要为这个文件做些什么,重要的是我会看到类似这些警告来自其他文件。

    编辑

    结构示例:

    struct HTTP_FILTER_PREPROC_HEADERS
    {
        //
        //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
        //  Header names should include the trailing ':'.  The special values
        //  'method', 'url' and 'version' can be used to retrieve the individual
        //  portions of the request line
        //
    
        internal GetHeaderDelegate GetHeader;
        internal SetHeaderDelegate SetHeader;
        internal AddHeaderDelegate AddHeader;
    
        UInt32  HttpStatus;               // New in 4.0, status for SEND_RESPONSE
        UInt32  dwReserved;               // New in 4.0
    }
    
    4 回复  |  直到 10 年前
        1
  •  183
  •   Community Jaime Torres    7 年前

    是的,这些可以被抑制。

    通常,我反对禁止警告,但在本例中,用于interop的结构绝对需要一些字段存在,即使您从未打算(或可以)使用它们,因此在本例中,我认为这是合理的。

    通常,要禁止这两个警告,您需要修复有问题的代码。第一个(“…从不使用”)通常是代码的早期版本遗留下来的代码味道。也许代码被删除了,但字段被留下了。

    第二种通常是错误使用字段的代码味道。例如,您可能错误地将属性的新值写回属性本身,而不是写回支持字段。


    取消“的警告 从未使用字段XYZ “你这样做:

    #pragma warning disable 0169
    ... field declaration
    #pragma warning restore 0169
    

    取消“的警告 字段XYZ从未分配给,并且始终具有其默认值XX。 “你这样做:

    #pragma warning disable 0649
    ... field declaration
    #pragma warning restore 0649
    

    为了自己找到这些警告号码(例如,我如何知道使用0169和0649),您可以这样做:

    • 正常编译代码,这将在Visual Studio的错误列表中添加一些警告。
    • 切换到输出窗口和生成输出,并查找相同的警告
    • 从相关消息中复制4位警告代码,如下所示:

      C:\dev\vs.net\consoleapplication19\consoleapplication19\program.cs(10,28): 警告CS 0649 :字段“consoleapplication19.program.dwreserved”从不 分配给并且将始终具有其默认值0


    告诫 :根据评论 @Jon Hanna 也许一些警告是为了这个,为了将来找到这个问题和答案。

    • 首先,也是最重要的,抑制警告的行为类似于吞下治疗头痛的药片。当然,有时候这可能是正确的做法,但这不是一个一刀切的解决方案。有时,头痛是一个你不应该掩饰的真正症状,和警告一样。最好是通过修复警告的原因来处理警告,而不是盲目地将其从生成输出中删除。
    • 既然这样说了,如果你需要压制一个警告,就按照我上面列出的模式来做。第一行代码, #pragma warning disable XYZK ,禁用警告 剩下的文件 或者至少直到 #pragma warning restore XYZK 被发现。最小化禁用这些警告的行数。上面的模式仅对一行禁用警告。
    • 另外,正如乔恩所提到的,一个关于你为什么要这样做的评论是个好主意。禁用一个警告绝对是一种代码气味,当没有原因地完成时,一个注释将阻止未来的维护人员花费时间,要么不知道为什么要这样做,要么甚至删除它并试图修复警告。
        2
  •  12
  •   floele    12 年前

    修复这些警告的另一个“解决方案”是使结构 public . 然后不会发出警告,因为编译器不知道字段是否在程序集之外使用(分配)。

    也就是说,“互操作”组件通常不应该是公共的,而是 internal private .

        3
  •  5
  •   Pencho Ilchev    13 年前

    我得到了生成 System.ComponentModel.INotifyPropertyChanged 事件作为字段实现,触发了CS0067警告。

    作为可接受答案中给出的解决方案的替代方案 我把这些字段转换成属性,警告消失了。 .

    这是有意义的,因为属性声明语法sugar被编译成一个引用该字段的字段加上getter和/或setter方法(在我的例子中是add/remove)。这满足编译器的要求,不会引发警告:

    struct HTTP_FILTER_PREPROC_HEADERS
    {
        //
        //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
        //  Header names should include the trailing ':'.  The special values
        //  'method', 'url' and 'version' can be used to retrieve the individual
        //  portions of the request line
        //
    
        internal GetHeaderDelegate GetHeader {get;set;}
        internal SetHeaderDelegate SetHeader { get; set; }
        internal AddHeaderDelegate AddHeader { get; set; }
    
        UInt32 HttpStatus { get; set; }               // New in 4.0, status for SEND_RESPONSE
        UInt32 dwReserved { get; set; }               // New in 4.0
    }
    
        4
  •  1
  •   ceztko Jeff Davis    10 年前

    C/C++用户有 (void)var; 禁止未使用的变量警告。 我刚刚发现,您还可以使用位运算符在C中抑制未使用的变量警告:

            uint test1 = 12345;
            test1 |= 0; // test1 is still 12345
    
            bool test2 = true;
            test2 &= false; // test2 is now false
    

    在VS2010 C_4.0和Mono2.10编译器中,这两个表达式都不会生成未使用的变量警告。