Comment #0 by andrej.mitrovich — 2011-04-19T13:22:50Z
int foo(ref int y)
{
y = 5;
return y;
}
void main()
{
int x = 1;
int y = 2;
switch (x = foo(y))
{
case y: // <- should not be allowed
writeln("x == y");
default:
}
assert(x == 5);
assert(y == 5);
}
Comment #1 by issues.dlang — 2011-06-19T03:49:01Z
Shockingly enough, according to TDPL (p. 72, first paragraph), this is completely valid. I was certain that case statements had to be known at compile time as well, but apparently that's not true.
Comment #2 by andrej.mitrovich — 2011-06-19T07:26:37Z
I don't really know why it wouldn't be allowed, unless there's some optimization technique that depends on it.
However:
void main()
{
int x;
int y;
switch (x)
{
case y + 1:
break;
default:
}
}
Error: variable y cannot be read at compile time
Error: case must be a string or an integral constant, not y + 1
Either runtime values are fully supported, or they are not. Some decision has to be made for this if the compiler and TDPL don't agree with each other. Should I open up a new thread in the NGs to discuss this?
Comment #3 by bearophile_hugs — 2011-06-19T07:28:44Z
I think this is a valid bug.
Comment #4 by smjg — 2011-06-19T10:37:14Z
http://www.digitalmars.com/d/1.0/statement.html#CaseStatement
"The case expressions must all evaluate to a constant value or array. They must be implicitly convertible to the type of the switch Expression."
http://www.digitalmars.com/d/2.0/statement.html#CaseStatement
"The case expressions must all evaluate to a constant value or array, or a runtime initialized const or immutable variable of integral type. They must be implicitly convertible to the type of the switch Expression."
Strangely, 1.068 (Win32) correctly rejects the code.
Comment #5 by code — 2013-11-30T08:41:30Z
*** Issue 11613 has been marked as a duplicate of this issue. ***
Comment #7 by andrej.mitrovich — 2016-08-27T21:43:06Z
As mentioned in the pull request the proposal to disallow this was rejected.
I would like to remind about this:
-----
import std.stdio;
void main()
{
int first = 1;
int second = 1;
switch (1)
{
case first:
{
writeln("first");
break;
}
case second:
{
writeln("second");
break;
}
default:
}
}
-----
The lexically first matching case will match. That's ok, but it should probably be documented if it's not (this style of code should be rare in the wild in any case).
Comment #8 by nick — 2023-04-27T14:39:28Z
(In reply to Andrej Mitrovic from comment #0)
> case y: // <- should not be allowed
comment #4:
> Strangely, 1.068 (Win32) correctly rejects the code.
Also rejected on Linux now:
switchmut.d(14): Error: `case` variables have to be `const` or `immutable`