Is there a way to get VS2008 to stop warning me about unreachable code?

前端 未结 8 1925
我在风中等你
我在风中等你 2021-02-05 02:04

I have a few config options in my application along the lines of

const bool ExecuteThis=true;
const bool ExecuteThat=false;

and then code that

相关标签:
8条回答
  • 2021-02-05 02:11

    First of all, I agree with you, you need to get rid of all warnings. Every little warning you get, get rid of it, by fixing the problem.

    Before I go on with what, on re-read, amounts to what looks like a rant, let me emphasis that there doesn't appear to be any performance penalty to using code like this. Having used Reflector to examine code, it appears code that is "flagged" as unreachable isn't actually placed into the output assembly.

    It is, however, checked by the compiler. This alone might be a good enough reason to disregard my rant.

    In other words, the net effect of getting rid of that warning is just that, you get rid of the warning.

    Also note that this answer is an opinion. You might not agree with my opinion, and want to use #pragma to mask out the warning message, but at least have an informed opinion about what that does. If you do, who cares what I think.

    Having said that, why are you writing code that won't be reached?

    Are you using consts instead of "defines"?

    A warning is not an error. It's a note, for you, to go analyze that piece of code and figure out if you did the right thing. Usually, you haven't. In the case of your particular example, you're purposely compiling code that will, for your particular configuration, never execute.

    Why is the code even there? It will never execute.

    Are you confused about what the word "constant" actually means? A constant means "this will never change, ever, and if you think it will, it's not a constant". That's what a constant is. It won't, and can't, and shouldn't, change. Ever.

    The compiler knows this, and will tell you that you have code, that due to a constant, will never, ever, be executed. This is usually an error.

    Is that constant going to change? If it is, it's obviously not a constant, but something that depends on the output type (Debug, Release), and it's a "#define" type of thing, so remove it, and use that mechanism instead. This makes it clearer, to people reading your code, what this particular code depends on. Visual Studio will also helpfully gray out the code if you've selected an output mode that doesn't set the define, so the code will not compile. This is what the compiler definitions was made to handle.

    On the other hand, if the constant isn't going to change, ever, for any reason, remove the code, you're not going to need it.

    In any case, don't fall prey to the easy fix to just disable that warning for that piece of code, that's like taking aspirin to "fix" your back ache problems. It's a short-term fix, but it masks the problem. Fix the underlying problem instead.

    To finish this answer, I'm wondering if there isn't an altogether different solution to your problem.

    Often, when I see code that has the warning "unreachable code detected", they fall into one of the following categories:

    1. Wrong (in my opinion) usage of const versus a compiler #define, where you basically say to the compiler: "This code, please compile it, even when I know it will not be used.".
    2. Wrong, as in, just plain wrong, like a switch-case which has a case-block that contains both a throw + a break.
    3. Leftover code from previous iterations, where you've just short-circuited a method by adding a return at some point, not deleting (or even commenting out) the code that follows.
    4. Code that depends on some configuration setting (ie. only valid during Debug-builds).

    If the code you have doesn't fall under any of the above settings, what is the specific case where your constant will change? Knowing that might give us better ways to answer your question on how to handle it.

    0 讨论(0)
  • 2021-02-05 02:11

    What about using preprocessor statements instead?

    #if ExecuteThis
        DoThis();
    #endif
    
    #if ExecuteThat
        DoThat();
    #endif
    
    0 讨论(0)
  • 2021-02-05 02:12

    To disable:

    #pragma warning disable 0162
    

    To restore:

    #pragma warning restore 0162
    

    For more on #pragma warning, see MSDN.

    Please note that the C# compiler is optimized enough to not emit unreachable code. This is called dead code elimination and it is one of the few optimizations that the C# compiler performs.

    And you shouldn't willy-nilly disable the warnings. The warnings are a symptom of a problem. Please see this answer.

    0 讨论(0)
  • 2021-02-05 02:13

    The easiest way is to stop writing unreachable code :D #DontDoThat

    0 讨论(0)
  • 2021-02-05 02:14

    The quickest way to "Just get rid of it" without modifying your code would be to use

    #pragma warning disable 0162
    

    On your Namespace, class or method where you want to supress the warning.

    For example, this wont throw the warning anymore:

    #pragma warning disable 0162
    namespace ConsoleApplication4
    {
      public class Program
      {
        public const bool something = false;
    
        static void Main(string[] args)
        {
            if (something) { Console.WriteLine(" Not something" ); }
    
        } 
     }
    

    However be warn that NO METHOD inside this namespace will throw the warning again... and well.. warnings are there for a reason (what if it happened when you did NOT planned it to be unreachable?)

    I guess a safer way would be to write the variables in a configuration file, and read them from there at the beginning of the program, that way you don't even need to recompile to have your different versions/releases! Just change the app file and go :D.

    about the speed penalty.. yes.. making it this way would inquire in a speed penalty... compared to using const but unless you are really worried about wating 1/100 of a millisecond more.. I would go for it that way.

    0 讨论(0)
  • 2021-02-05 02:25

    The fact that you have the constants declared in code tells me that you are recompiling your code with each release you do, you are not using "contants" sourced from your config file.

    So the solution is simple: - set the "constants" (flags) from values stored in your config file - use conditional compilation to control what is compiled, like this:

    #define ExecuteThis
    //#define ExecuteThat
    
    public void myFunction() {
    #if ExecuteThis
        DoThis();
    #endif
    #if ExecuteThat
        DoThat();
    #endif
    }
    

    Then when you recompile you just uncomment the correct #define statement to get the right bit of code compiled. There are one or two other ways to declare your conditional compilation flags, but this just gives you an example and somewhere to start.

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