Thread overview
switch statement with variable branches
Jan 19, 2017
Yuxuan Shui
Jan 19, 2017
Ali Çehreli
Jan 19, 2017
Yuxuan Shui
Jan 19, 2017
Stefan Koch
January 19, 2017
Somehow I can't use ubyte variables behind 'case', but ulong works fine. Why is that?

void main() {
	alias TestType = ulong; // won't compile if = ubyte
	import std.stdio;
	TestType a,b,c;
	readf("%s %s %s ", &a, &b, &c);
	switch(c){
		case a: writeln("a");break;
		case b: writeln("b");break;
		default: assert(false);
	}
}
January 18, 2017
On 01/18/2017 05:22 PM, Yuxuan Shui wrote:
> Somehow I can't use ubyte variables behind 'case', but ulong works fine.
> Why is that?
>
> void main() {
>     alias TestType = ulong; // won't compile if = ubyte
>     import std.stdio;
>     TestType a,b,c;
>     readf("%s %s %s ", &a, &b, &c);
>     switch(c){
>         case a: writeln("a");break;
>         case b: writeln("b");break;
>         default: assert(false);
>     }
> }

case expressions must be constants:

  "The case expressions must all evaluate to a constant value or
   array, or a runtime initialized const or immutable variable of
   integral type."

  https://dlang.org/spec/statement.html#SwitchStatement

The fact that it compiles for ulong looks like a bug to me. It compiles probably because switch is most likely implemented in terms of a chained if-else-if statements by the compiler and it just works because there is no explicit check whether they are constant or not.

Ali

January 19, 2017
On Thursday, 19 January 2017 at 02:00:10 UTC, Ali Çehreli wrote:
> On 01/18/2017 05:22 PM, Yuxuan Shui wrote:
>> Somehow I can't use ubyte variables behind 'case', but ulong works fine.
>> Why is that?
>>
>
> case expressions must be constants:
>
>   "The case expressions must all evaluate to a constant value or
>    array, or a runtime initialized const or immutable variable of
>    integral type."
>
>   https://dlang.org/spec/statement.html#SwitchStatement
>
> The fact that it compiles for ulong looks like a bug to me. It compiles probably because switch is most likely implemented in terms of a chained if-else-if statements by the compiler and it just works because there is no explicit check whether they are constant or not.
>
> Ali

If you try:

void main() {
    alias TestType = ulong; // won't compile if = ubyte
    import std.stdio;
    TestType a,b,c;
    readf("%s %s %s ", &a, &b, &c);
    final switch(c){
        case a: writeln("a");break;
        case b: writeln("b");break;
        default: assert(false);
    }
}

Then the error message:

test.d(7): Error: case variables not allowed in final switch statements
test.d(8): Error: case variables not allowed in final switch statements

Makes it looks like that "case variable" is an intended feature.

January 19, 2017
On Thursday, 19 January 2017 at 01:22:56 UTC, Yuxuan Shui wrote:
> Somehow I can't use ubyte variables behind 'case', but ulong works fine. Why is that?
>
> void main() {
> 	alias TestType = ulong; // won't compile if = ubyte
> 	import std.stdio;
> 	TestType a,b,c;
> 	readf("%s %s %s ", &a, &b, &c);
> 	switch(c){
> 		case a: writeln("a");break;
> 		case b: writeln("b");break;
> 		default: assert(false);
> 	}
> }

It is a bug that this code compiled.
Case Variables can only be used on const values, to prevent mutation of them inside the switch itself.

try to make the type a const ubyte.