1118 – weird switch statement behaviour

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1118 - weird switch statement behaviour
Summary: weird switch statement behaviour
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Linux
: P2 normal
Assignee: Walter Bright
URL:
Keywords: accepts-invalid, spec
Depends on:
Blocks:
Reported: 2007年04月09日 17:59 UTC by Manuel König
Modified: 2014年02月16日 15:23 UTC (History)
1 user (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Manuel König 2007年04月09日 17:59:28 UTC
The documentation for the switch statement says:
 SwitchStatement:
	 switch ( Expression ) ScopeStatement
So there must not be 'case', 'default' or scoping brackets after the switch. Hence this would be valid code (and actually compiles, throwing a 'Switch Default' error for the first example):
	switch (1)
		for (int i=0; i<5; i++) writefln(i);
	// another, yet acceptable but ugly looking example example
	switch (true)
	case true: writefln("foo");
	switch (5)
	{
		// do anything but no switch/case
		writefln("foo");
	}
But beside a ScopeStatement, even a normal Statement gets accepted by the compiler (at least I could not figure out a transition from a ScopeStatement to an ExpressionStatement):
 switch(2)
 writefln("foo");
_________________________________________________________________
Examples were tested on Ubuntu Linux with
 * dmd 1.010
 * gdc 0.23
_________________________________________________________________
PS: I think a definition like this would do the job:
 SwitchStatement:
	 switch ( Expression ) { SwitchItemList }
 SwitchItemList:
 SwitchItem
 SwitchItem SwitchItemList
 SwitchItem:
 CaseStatement
 DefaultStatement
Comment 1 BCS 2007年04月09日 18:06:33 UTC
What about cases like this:
switch(i)
{
 while(i)
 {
 foo();
 case 0: bar();
 case 1: baz();
 case 3: i--;
 }
}
Comment 2 Manuel König 2007年04月09日 18:25:23 UTC
> What about cases like this:
> 
> switch(i)
> {
> while(i)
> {
> foo();
> case 0: bar();
> case 1: baz();
> case 3: i--;
> }
> }
> 
> 
Nice idea, never had to use it that way. Think this issue should be 
tagged as INVALID...
But looking at the examples given before, it would be nice if the 
compiler would give at least a warning about missing switch labels.
Comment 3 BCS 2007年04月09日 18:41:13 UTC
Not having a case might not be a problem: tuples can be foreached to generate cases and a zero length tuple might be valid. You would however expect their to be a default in that case.
int Foo(A...)(int i)
{
 switch(i)
 {
 default:
 // code
 break;
 foreach(a;A)
 {
 case a:
 // code
 // break;
 }
 }
}
Comment 4 Manuel König 2007年04月09日 19:20:20 UTC
> ------- Comment #3 from shro8822@uidaho.edu 2007年04月09日 18:41 -------
> Not having a case might not be a problem: tuples can be foreached to generate
> cases and a zero length tuple might be valid. You would however expect their to
> be a default in that case.
> 
> int Foo(A...)(int i)
> {
> switch(i)
> {
> default:
> // code
> break;
> foreach(a;A)
> {
> case a:
> // code
> // break;
> }
> }
> }
> 
> 
Wow, again I'm amazed by D's features! But I could not compile your code 
(yet a real bug :P ). But I could find a workaround:
import std.stdio;
// your version (should work, but it doesn't)
void Foo1(A...)(int i)
{
	switch (i)
	{
		foreach(a; A)
		{
		case a:		// line 9
			writefln(a);
		}
	}
}
// workaround (does exactly the same thing, but with more clumsy code)
void Foo2(A...)(int i)
{
	switch (i)
	{
		foreach(j, a; A)
		{
		case A[j]:
			writefln(a);
		}
	}
}
void main()
{
	//Foo1!(1,2,3,4,5)(1); // line 29
	Foo2!(1,2,3,4,5)(1);
}
The output is
1
2
3
4
5
just as expected. But uncommenting Foo1 gives an error. Error log from 
Code::Blocks:
hello.d:9: Error: case must be a string or an integral constant, not a
hello.d:9: Error: case must be a string or an integral constant, not a
hello.d:9: Error: duplicate case 0 in switch statement
hello.d:9: Error: case must be a string or an integral constant, not a
hello.d:9: Error: duplicate case 0 in switch statement
hello.d:9: Error: case must be a string or an integral constant, not a
hello.d:9: Error: duplicate case 0 in switch statement
hello.d:9: Error: case must be a string or an integral constant, not a
hello.d:9: Error: duplicate case 0 in switch statement
hello.d:29: template instance hello.Foo1!(1,2,3,4,5) error instantiating
:: === Build finished: 10 errors, 0 warnings ===
I think that's worth a bug report.
Comment 5 Walter Bright 2007年07月01日 13:29:09 UTC
Fixed DMD 1.018 and DMD 2.002


AltStyle によって変換されたページ (->オリジナル) /