Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler warning when using const boolean

Tags:

c#

I stumbled on a surprising compiler warning using the following code:

private const bool DEFAULT_SETTING = false;
//...
string aString = (DEFAULT_SETTING) ? "1" : "0";

which generates the warning warning CS0429: Unreachable expression code detected.

After initially being puzzled, I realised the compiler is not wrong because the value of DEFAULT_SETTING is constant and cannot change. Therefore the ? "1" part of the ternary operator can never be reached. But neither is the compiler completely right because myself or a future developer may want (or need) to change the default value without breaking the code.

Is there better way to use a default setting similar to the above context which does not generate the warning?

Note: You may want to know why I would want to convert false into "0"...it is to save to a settings XML file. When the file is missing, the software automatically generates a shiny new XML file with default settings.

like image 520
AlainD Avatar asked Feb 10 '17 23:02

AlainD


3 Answers

Is there better way to use a default setting similar to the above context which does not generate the warning?

Yes.

But first: stop using SHOUTY_SNAKE_CASING right now. It makes it look like you're a C programmer. C# uses camelCasing and PascalCasing.

Now to your question. If a named value can change then by definition it is not a constant. Use constants only for things which never change. Pi is a constant. The number of protons in an atom of gold is a constant. The name of your program is not a constant, whether this is the debug or retail build is not a constant, and so on. Those things change.

The compiler is within its rights to warn you about your code because it appears to be making a choice based on something which never changes, and therefore is likely a bug.

This isn't just a convention; the semantics of the C# language assume that a constant will not change ever. For example, if you have a public constant Foo in Foo.DLL, and it is consumed by code in Bar.EXE, recompiling Foo.DLL with a different value for Foo does not update the value of Foo automatically in Bar.EXE. The C# compiler will assume that Foo will never change and makes a copy of its value in Bar.EXE.

To represent the concept "this thing doesn't change in my program, but it could change in a different instance of my program" use readonly:

private static readonly bool DefaultSetting = false;
...
string aString = DefaultSetting ? "1" : "0";
like image 55
Eric Lippert Avatar answered Nov 09 '22 10:11

Eric Lippert


You can use compiler directive. this line is the first line:

#define DEFAULT_SETTING

then remain as:

#if DEFAULT_SETTING
    string aString = "1";
#else
    string aString = "0";
#endif

if you comment the #define DEFAULT_SETTING the string aString = "0"; line is active for compiling otherwise string aString = "1"; is active.

like image 32
Hossein Golshani Avatar answered Nov 09 '22 09:11

Hossein Golshani


Use an extension like this:

public static class BooleanExtensions {
   public static string ToOneOrZero(this bool value) {
      return value ? "1" : "0";
   }
}

Usage:

var val = DEFAULT_SETTING.ToOneOrZero();

You will not get a warning and it is cleaner-I think.

like image 2
CodingYoshi Avatar answered Nov 09 '22 09:11

CodingYoshi