1

I've got some code that needs to work slightly differently in debug and release modes. It has a constant called PrettyPrint that is set to true in some modes and false in others, and I sometimes change those around.

#if DEBUG
        public const bool PrettyPrint = true;
#else
        public const bool PrettyPrint = false;
#endif

// ...snip...
string start, end, comma, innerIndentation;
if (Printer.PrettyPrint) {
    innerIndentation = indentation + "  ";
    start = "[\n";
    end = indentation + "]";
    comma = ",\n" + innerIndentation;
} else {
    innerIndentation = "";
    start = "[";
    end = "]";
    comma = ",";
}
// Then do some prints using the initialized strings as constants

This works great, and the compiler is smart enough to optimize the if away. However, I get an annoying warning:

warning CS0162: Unreachable code detected

Is there a way to avoid this warning without doing any of the following:

  • using #if directly in the code - as it makes that part of the code quite ugly and I'd like to avoid #ifs as much as possible.
  • suppressing CS0162 for other cases - as I find that warning invaluable in finding broken code.

How do I use an #if DEBUG statement without the IDE believing that all code that follows is unreachable?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
configurator
  • 40,828
  • 14
  • 81
  • 115
  • 1
    Replace *const* by *readonly*. – Hans Passant Feb 25 '11 at 01:32
  • Has the compiler been tricked or something? I don't see any unreachable code – Nick Rolando Feb 25 '11 at 01:37
  • 1
    @Nicklamort, the compiler notices that `Printer.PrettyPrint` is a `const` and therefore will never change. i.e. that `if` statement will always evaluate to `true`, meaning the `else` portion will be unreachable (and the other way around when not in debug mode) – BinaryTox1n Feb 25 '11 at 01:39
  • @BT So it has been 'tricked' then (since there are two declaration statements). Because it WILL change if DEBUG changes, no? Therefore the code is reachable – Nick Rolando Feb 25 '11 at 01:46
  • 1
    @Nicklamort: DEBUG is set at compile-time. So for a given compile, PrettyPrint will either always be true or always be false. – Nick Lewis Feb 25 '11 at 01:48
  • @Nick Lewis I know. The compiler should only give this warning for code that is unreachable, regardless if its between executions or not. For example, having code after a return statement. I would see that as a compiler bug, but that's just me – Nick Rolando Feb 25 '11 at 01:51
  • 1
    What do you mean by "between executions"? It won't matter how many times you run the code, the constant will either be always true or always false until the code is recompiled with a different DEBUG flag. Either way, one of the code blocks is unreachable, and it's entirely appropriate that the compiler warn you about it. – lesscode Feb 25 '11 at 03:09

5 Answers5

2

While I currently don't have an idea how to work it into your code, you might find the ConditionalAttribute helpful. You'd get around using preprocessor directives, but you might have to rework your code.

Femaref
  • 60,705
  • 7
  • 138
  • 176
2

You could do the following to get round it.

Printer.PrettyPrint.Equals(true)
1

You could change PrettyPrint to a normal field instead of const.
You'll lose the compiler optimization, but that shouldn't matter.

I'm pretty sure you could also make it readonly without getting the warning; try it.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

You could try:

innerIndentation = Printer.PrettyPrint ? indentation + " " : "";

start = Printer.PrettyPrint ? "[\n" : "[";

end = Printer.PrettyPrint ? indentation + "]" : "]";

comma = Printer.PrettyPrint ? ",\n" + innerIndentation : ",";

But if it were me, I would just use an #if #else

BinaryTox1n
  • 3,486
  • 1
  • 36
  • 44
0

Change the PrettyPrint from a const to a field.

#if DEBUG          
    public bool PrettyPrint = true;  
#else 
    public bool PrettyPrint = false;  
#endif
Richard Schneider
  • 34,944
  • 9
  • 57
  • 73