C# Compiler should give warning but doesn't?

后端 未结 7 1102
北恋
北恋 2020-12-03 14:05

Someone on my team tried fixing a \'variable not used\' warning in an empty catch clause.

try { ... } catch (Exception ex) { }

-> gives a w

相关标签:
7条回答
  • 2020-12-03 14:38

    I think the person that answers this will need some insight into how the compiler works. However, something like FxCop would probably catch this.

    0 讨论(0)
  • 2020-12-03 14:39

    In this case the compiler detects that s is written but not read, and deliberately suppresses the warning.

    The reason is because C# is a garbage-collected language, believe it or not.

    How do you figure that?

    Well, consider the following.

    You have a program which calls a method DoIt() that returns a string. You do not have the source code for DoIt(), but you wish to examine in the debugger what its return value is.

    Now in your particular case you are using DoIt() for its side effects, not its return value. So you say

    DoIt(); // discard the return value
    

    Now you're debugging your program and you go to look at the return value of DoIt() and it's not there because by the time the debugger breaks after the call to DoIt(), the garbage collector might have already cleaned up the unused string.

    And in fact the managed debugger has no facility for "look at the thing returned by the previous method call". The unmanaged C++ debugger has that feature because it can look at the EAX register where the discarded return value is still sitting, but you have no guarantee in managed code that the returned value is still alive if it was discarded.

    Now, one might argue that this is a useful feature and that the debugger team should add a feature whereby returned values are kept alive if there's a debugger breakpoint immediately following a method execution. That would be a nice feature, but I'm the wrong person to ask for it; go ask the debugger team.

    What is the poor C# developer to do? Make a local variable, store the result in the local variable, and then examine the local in the debugger. The debugger does ensure that locals are not garbage collected aggressively.

    So you do that and then the compiler gives you a warning that you've got a local that is only written to and never read because the thing doing the reading is not part of the program, it's the developer sitting there watching the debugger. That is a very irritating user experience! Therefore we detect the situation where a non-constant value is being assigned to a local variable or field that is never read, and suppress that warning. If you change up your code so that instead it says string s = "hello"; then you'll start getting the warning because the compiler reasons, well, this can't possibly be someone working around the limitations of the debugger because the value is right there where it can be read by the developer already without the debugger.

    That explains that one. There are numerous other cases where we suppress warnings about variables that are never read from; a detailed exegisis of all the compiler's policies for when we report warnings and when we do not would take me quite some time to write up, so I think I will leave it at that.

    0 讨论(0)
  • 2020-12-03 14:42

    Resharper would catch that

    0 讨论(0)
  • 2020-12-03 14:43

    Properties are just methods, and there's nothing stopping anyone from putting some code that does something in the ex.Message property. Therefore, while you may not be doing anything with s, calling ex.Message COULD potentially have value....

    0 讨论(0)
  • 2020-12-03 14:53

    The variable s is used... to hold a reference to ex.Message. If you had just string s; you would get the warning.

    0 讨论(0)
  • 2020-12-03 14:56

    It's not really the job of a compiler to work out every single instance and corner case when a variable may or may not be used. Some are easy to spot, some are more problematic. Erring on the side of caution is the sensible thing to do (especially when warnings can be set to be treated as errors - imagine if software didn't compile just because the compiler thought you weren't using something you were). Microsoft Compiler team specifically say:

    "...our guidance for customers who are interested in discovering unused elements in their code is to use FxCop. It can discover unused fields and much more interesting data about your code."

    -Ed Maurer, Development Lead, Managed Compiler Platform

    0 讨论(0)
提交回复
热议问题