Suppressing "is never used" and "is never assigned to" warnings in C#

C#Visual StudioSuppress Warnings

C# Problem Overview


I have a HTTPSystemDefinitions.cs file in C# project which basically describes the older windows ISAPI for consumption by managed code.

This includes the complete set of Structures relevant to the ISAPI not all or which are consumed by code. On compilation all the field members of these structures are causing a warning like the following:-

> Warning Field 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' is never assigned to, and will always have its default value null

or

> Warning The field 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus' is never used

Can these be disabled with #pragma warning disable? If so what would the corresponding error numbers be? If not is there anything else I can do? Bear in mind that I only what to do this for this file, its important that I get see warnings like these coming from other files.

Edit

Example struct:-

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
}

C# Solutions


Solution 1 - C#

Yes, these can be suppressed.

Normally, I'm opposed to suppressing warnings, but in this case, structs used for interop absolutely requires some fields to be present, even though you never intend to (or can) use them, so in this case I think it should be justified.

Normally, to suppress those two warnings, you would fix the offending code. The first ("... is never used") is usually a code-smell of leftovers from earlier versions of the code. Perhaps code was deleted, but fields left behind.

The second is usually a code-smell for incorrectly used fields. For instance, you might incorrectly write the new value of a property back to the property itself, never writing to the backing field.


To suppress warnings for "Field XYZ is never used", you do this:

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

To suppress warnings for "Field XYZ is never assigned to, and will always have its default value XX", you do this:

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

To find such warning numbers yourself (ie. how did I know to use 0169 and 0649), you do this:

  • Compile the code as normal, this will add some warnings to your error list in Visual Studio

  • Switch to the Output window, and the Build output, and hunt for the same warnings

  • Copy the 4-digit warning code from the relevant message, which should look like this:

    > C:\Dev\VS.NET\ConsoleApplication19\ConsoleApplication19\Program.cs(10,28): warning CS0649: Field 'ConsoleApplication19.Program.dwReserved' is never assigned to, and will always have its default value 0


Caveat: As per the comment by @Jon Hanna, perhaps a few warnings is in order for this, for future finders of this question and answer.

  • First, and foremost, the act of suppressing a warning is akin to swallowing pills for headache. Sure, it might be the right thing to do sometimes, but it's not a catch-all solution. Sometimes, a headache is a real symptom that you shouldn't mask, same with warnings. It is always best to try to treat the warnings by fixing their cause, instead of just blindly removing them from the build output.

  • Having said that, if you need to suppress a warning, follow the pattern I laid out above. The first code line, #pragma warning disable XYZK, disables the warning for the rest of that file, or at least until a corresponding #pragma warning restore XYZK is found. Minimize the number of lines you disable these warnings on. The pattern above disables the warning for just one line.

  • Also, as Jon mentions, a comment as to why you're doing this is a good idea. Disabling a warning is definitely a code-smell when done without cause, and a comment will prevent future maintainers from spending time either wondering why you did it, or even by removing it and trying to fix the warnings.

Solution 2 - C#

Another "solution" to fix these warnings is by making the struct public. The warnings are not issued then because the compiler can't know whether or not the fields are being used (assigned) outside of the assembly.

That said, "interop" components should usually not be public, but rather internal or private.

Solution 3 - C#

I got VS to generate the implementation skeleton for System.ComponentModel.INotifyPropertyChanged and the events were implemented as fields which triggered the CS0067 warnings.

As an alternative to the solution given in the accepted answer I converted the fields into properties and the warning disappeared.

This makes sense since the property declarations syntax sugar are compiled into a field plus getter and/or setter methods (add/remove in my case) which reference the field. This satisfies the compiler and the warnings are not raised:

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
}

Solution 4 - C#

C/C++ users have (void)var; to suppress unused variables warnings. I just discovered you can also suppress unused variables warnings in C# with bitwise operators:

        uint test1 = 12345;
        test1 |= 0; // test1 is still 12345

        bool test2 = true;
        test2 &= false; // test2 is now false

Both expressions don't produce unused variable warnings in VS2010 C# 4.0 and Mono 2.10 compilers.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAnthonyWJonesView Question on Stackoverflow
Solution 1 - C#Lasse V. KarlsenView Answer on Stackoverflow
Solution 2 - C#floeleView Answer on Stackoverflow
Solution 3 - C#Pencho IlchevView Answer on Stackoverflow
Solution 4 - C#ceztkoView Answer on Stackoverflow