-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiler does not detect exhaustive bool switch #24865
Comments
The situation is the same with enums: using System;
public enum E { Foo, Bar }
public class C {
public void M(E e) {
bool b;
switch (e) {
case E.Foo:
b = true;
break;
case E.Bar:
b = true;
break;
}
Console.WriteLine(b); // error CS0165: Use of unassigned local variable 'b'
}
} Yes, technically one could argue that a match against an enum can't be exhaustive given that the enums value technically could be some arbitrary integer that doesn't match to one of its members but I seem to recall a conversation on this repo somewhere where the compiler wouldn't consider those cases. I'll try to scan for such a conversation and link it here if I find it. |
I might be thinking of this conversation: #11438 In which case it was explicitly decided that matching |
Just bringing this back up again to find out what the compiler will do. If the compiler considered ( bool x = LolBool.Value;
switch (x)
{
case true:
case false:
break;
default:
throw new Exception("lol");
}
public static class LolBool
{
public static readonly bool Value = new LolBoolUnion(0b10000000).BoolValue;
[StructLayout(LayoutKind.Explicit)]
private struct LolBoolUnion
{
[FieldOffset(0)]
private readonly byte byteValue;
[FieldOffset(0)]
public readonly bool BoolValue;
public LolBoolUnion(byte byteValue) : this()
{
this.byteValue = byteValue;
}
}
} Or would the implementation of the switch then change to be like bool x = LolBool.Value;
bool trueVariable = true;
if (x == trueVariable)
Console.WriteLine("This does not happen because 0b10000000 != 0b00000001");
const bool trueConst = true;
if (x == trueConst)
Console.WriteLine("But this does, because it's reduced to `if (x)` which is ultimately a non-zero check"); |
This actually also applies to |
@tannergooding Does it? It's possible to store more than 8 bits in a I would expect this to show up in the wild in combination with interop. |
A |
The code generated for a pattern-match on a boolean constant like We have previously decided that enumerating the values of types other than switch (myByte)
{
case in 0 to 127: break;
case in 128 to 255: break;
} The reason for this bug (#24865) is that the compiler always considers a |
To work around this (#24865) bug in the compiler, add |
Would be nice to get exhaustive matching on dotnet/csharplang#1410 (comment) Update: Using |
This is now fixed in the |
Reported by @HaloFour in dotnet/csharplang#1054 (comment)
The compiler does not determine
b
to be definitely assigned unless you also havedefault
case which assignsb
:That's clearly exhaustive.
The text was updated successfully, but these errors were encountered: