117

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
}
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • Can you show the declaration of those fields, or rather, the struct they're in? ie. give an example. – Lasse V. Karlsen Sep 29 '10 at 11:07
  • 11
    If these are interop definitions, then normally you'd put `[StructLayout(LayoutKind.Sequential)]` to ensure the memory layout is correct (in the current implementation it will be even without this attribute, but AFAIK it isn't guaranteed). If I remember correctly, the C# compiler detects the presence of this attribute and automatically suppresses those warnings as it knows fields have to be there for interop. (I could be wrong about this, hence posting as a comment instead of an answer). – Greg Beech Oct 01 '10 at 08:43
  • @Greg: That's useful info I'll investigate I would rather the warning not be generated rather than suppress them. – AnthonyWJones Oct 01 '10 at 08:50
  • 1
    +1 for using `StructLayout`. It seems cleaner than suppressing the warnings themselves. – Deanna Nov 10 '14 at 09:03
  • @GregBeech You are right! That still applies for .NET Standard projects on VS2017. – zwcloud Apr 19 '17 at 07:28

4 Answers4

208

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.
Community
  • 1
  • 1
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 11
    I'd recommend further to the answer above, that the scope of the disabling be as small as possible (to avoid disabling it somewhere where it is useful) and to always accompany a disabling with a comment as to why you are disabling, e.g. `//exists for interop` in this case. – Jon Hanna Sep 29 '10 at 11:19
  • Thanks a lot. Its a strange choice that VS doesn't include a column for these numbers in the Error List window. – AnthonyWJones Sep 29 '10 at 11:21
  • @Anthony, I agree, but they're perhaps not useful in the majority of cases for most people, so it definitely saves screen real-estate for the actual message. But I too would want to see it, perhaps even just on a tooltip. – Lasse V. Karlsen Sep 29 '10 at 11:27
  • @Lasse: The Error List window does have a "Show Columns" option on its context menu so it could at least have been an unselected item in there. – AnthonyWJones Sep 29 '10 at 11:52
  • 2
    As Jon says, commenting the "why" is very important. In addition, I usually add at least part of the text of the warning message to the comment e.g. // Suppress "is never assigned to..." warning. Save future maintainers the annoyance of having to look up the warning code - after all, it could be you! – Tom Bushell Sep 29 '10 at 18:26
  • I just hit a different way that the problem cropped up--I have two related programs with over 80% code overlap--and in some of that overlapping code there are a few fields used by one one of the two programs. I've been beating my head on why Resharper wouldn't help before I finally twigged that these were from VS not Resharper. – Loren Pechtel Sep 16 '14 at 01:40
  • 1
    Its not immediately obvious but you can use Find in the Output window via CTRL+F, type in "warning", click "Find All" and get every warning quickly, with warning numbers displayed. That said the `[StructLayout(LayoutKind.Sequential)]` attribute handles interop much better as per Greg Beech's comment on the question. – Ryan Buddicom Nov 18 '14 at 08:23
  • To suppress warnings for "Field XYZ is never used", you do this: warning number is 0168 not 0169 – Dean Van Greunen Nov 22 '16 at 12:11
  • 2
    Commenting to say that for Unity3D users, the warning numbers are 0414 for private fields and 0219 for local variables, not 169 (which throws a warning about unable to restore the warning instead). – Draco18s no longer trusts SE Jan 23 '17 at 04:11
  • this is also perfect for cases where some client component consumes only parts of a service which is based on shared classes or structures that are deserialized into: they need to be present for deserialization, but are not necessarily used. IntelliSense and compiler cannot know that. – Cee McSharpface Jun 29 '17 at 18:44
  • Using this on a try/catch block did not suppress an unused exception warning. – Zimano Mar 26 '19 at 10:11
  • "unused exception"? That doesn't make sense. If you're talking about a `catch (Exception ex)`, where you don't use `ex`, then simply remove `ex`. Can you elaborate on what exactly you meant @Zimano? – Lasse V. Karlsen Mar 26 '19 at 11:07
  • @LasseVågsætherKarlsen I'm sorry, I meant unused variable; the `ex` in `catch (Exception ex)`. Of course it should be removed in that case, but nevertheless I would expect it to still surpress the warning! – Zimano Mar 26 '19 at 12:07
  • `#pragma warning disable 0168` does in fact suppress that warning, you sure you used the right CSxxxx number? – Lasse V. Karlsen Mar 26 '19 at 13:59
15

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.

floele
  • 3,668
  • 4
  • 35
  • 51
  • 2
    Nice, this does hide the warning… but setting such a `struct` as `public` is more likely to be a mistake than the warning we’re trying to mask. (You probably shouldn’t be unnecessarily exposing types used for internal implementation and types with public fields probably do not belong in a public API). Just to reinforce your advice that such types should be “rather `internal` or `private`” ;-). – binki Jun 10 '14 at 03:28
  • awesome thanks - this is what I needed. I'm using `JsonConvert.DeserializeObject` and I'm deserializing into a public class that just has all of the properties exposed so that I know what will be returned. Just making it a public class that's empty with all public strings is nice short code and now no more warnings. Maybe using a dynamic class would be better as you don't have to explicitly state what's in the array, but I think this will be a nice reference for anyone hoping to use the object. – user1274820 Sep 04 '19 at 15:21
6

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
}
Pencho Ilchev
  • 3,201
  • 18
  • 21
  • Your solution is much graceful than disabling the warning, but it may interfere with some field-only attributes, e.g. MarshalAsAttribute. – HuBeZa Feb 05 '12 at 16:28
  • 1
    Info: The actual private fields generated in this situation might have "strange" names such as `k__BackingField`, depending on implementation details of the C# compiler used. – Jeppe Stig Nielsen Mar 19 '15 at 13:20
1

C/C++ users have (void)var; to suppress unused variables warnings. @Pang in the comments reports that the variable discards can be used for warnings suppression:

_ = variable;

This is probably available since C# 7.0, that introduce such use of underscore in the language syntax. In previous versions of the language once could suppress unused variables warnings in C# with bitwise operators, for types where such operators are defined:

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

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

Using such strategy is certainly fishy and to use as last resort. Better to upgrade language support and use variable discard syntax.

ceztko
  • 14,736
  • 5
  • 58
  • 73
  • 4
    Works for `uint`, but not for other types, as `Exception`. Do you know a generic trick equivalent to the C/C++ `var;`? – manuell Nov 24 '15 at 12:10
  • 1
    @manuell hello from the future! You can use `error.ToString();` for a variable of type `Exception` – Sv443 Jun 24 '19 at 10:51
  • Thanks from now. That trick does add real code at runtime, right? – manuell Jun 24 '19 at 14:58
  • 2
    `_ = test1;` looks better. – Pang Nov 18 '20 at 09:08
  • @Pang Add your own answer so we can upvote. By the time I answered the unused suppressor wasn't in the language – ceztko Dec 01 '20 at 12:13
  • This is incredibly confusing code, imo, and one would need to annotate that the line is there to repress a warning, but at that point one might as well use `#pragma`, which more clearly tells the reader what is going on. – Jaacko Torus Aug 22 '22 at 14:31
  • 1
    @JaackoTorus that was just an old discovery pre C# 7.0. I would not use it in my code, unless very well documented. Since Pang didn't add his own answer, as I suggested, I updated my answer to mention variable discard syntax – ceztko Aug 22 '22 at 15:28