www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: No more fall through in case statement?

reply bearophile <bearophileHUGS lycos.com> writes:
Bill Baxter:
 I'm no C# guy but that looks like a nice way to fix C's switch.

I think the C switch is broken in 2 or more ways, so I'd like to see D improve it. This is some code I have shown time ago: import std.stdio: writefln; void main(string[] args) { switch (args[1]) { int x = 1; // NOT initialized? case "1": writefln("1! x=", x); break; case "2": writefln("2! x=", x); break; } } More on switch-induced bugs: http://www.soft.com/AppNotes/attcrash.html
"goto case 5" looks like something straight out of Walter's playbook, too.<

I don't like that goto too much... You usually just want do go down (and by default you want to go to the end of the switch).
 But it's been discussed many times now and it doesn't seem likely Walter's
going to change it in D.<

I agree with Walter when he says it's better that if a syntax that looks like C works like C (D goes against this rule few times). So we need a syntax that looks different. Instead of switch{} it may be used caseof{}, plus the "default" statement, plus a new statement like "fall" (or something similar) that tells the compiler just to not break, so it's just the opposite of C :-) As example, this is a part of the std.string.capwords function: switch (s[i]) { case ' ': case '\t': case '\f': case '\r': case '\n': case '\v': if (inword) { r ~= capitalize(s[istart .. i]); inword = false; } break; default: if (!inword) { if (r.length) r ~= ' '; istart = i; inword = true; } break; } With that syntax it becomes: caseof (s[i]) { case ' ': fall; case '\t': fall; case '\f': fall; case '\r': fall; case '\n': fall; case '\v': if (inword) { r ~= capitalize(s[istart .. i]); inword = false; } default: if (!inword) { if (r.length) r ~= ' '; istart = i; inword = true; } } D already follows such "inversion rule" regerding C in some cases, like here: int a = void; In a safe(r) language the default syntax/behavior *must* be the safer one, expecially when this has no/little costs in terms of speed/memory. Bye, bearophile
Jan 03 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
bearophile:

 caseof (s[i]) {
     case ' ':  fall;
     case '\t': fall;
     case '\f': fall;
     case '\r': fall;
     case '\n': fall;
     case '\v':
         if (inword) {
             r ~= capitalize(s[istart .. i]);
             inword = false;
         }
 
     default:
         if (!inword) {
             if (r.length)
             r ~= ' ';
             istart = i;
             inword = true;
         }
 }

Let's try again, 2 keywords less: caseof (s[i]) { case ' ': continue; case '\t': continue; case '\f': continue; case '\r': continue; case '\n': continue; case '\v': if (inword) { r ~= capitalize(s[istart .. i]); inword = false; } else: if (!inword) { if (r.length) r ~= ' '; istart = i; inword = true; } } :-) Bye, bearophile
Jan 03 2008
parent reply Leonard Dahlmann <leo.dahlmann gmail.com> writes:
bearophile Wrote:

 bearophile:
 
 caseof (s[i]) {
     case ' ':  fall;
     case '\t': fall;
     case '\f': fall;
     case '\r': fall;
     case '\n': fall;
     case '\v':
         if (inword) {
             r ~= capitalize(s[istart .. i]);
             inword = false;
         }
 
     default:
         if (!inword) {
             if (r.length)
             r ~= ' ';
             istart = i;
             inword = true;
         }
 }

Let's try again, 2 keywords less: caseof (s[i]) { case ' ': continue; case '\t': continue; case '\f': continue; case '\r': continue; case '\n': continue; case '\v': if (inword) { r ~= capitalize(s[istart .. i]); inword = false; } else: if (!inword) { if (r.length) r ~= ' '; istart = i; inword = true; } } :-) Bye, bearophile

I doubt that 'continue' can be used there - what if we have a caseof in a loop? foreach(x; y) { caseof(s[i]) { case '': continue; // fallthrough or continue the loop? } } One could workaround this by giving the loop a label and using it with 'continue', but still, this might be confusing for beginners.
Jan 03 2008
parent 0ffh <frank youknow.what.todo.interNETz> writes:
Leonard Dahlmann wrote:
 I doubt that 'continue' can be used there - what if we have a caseof in a loop?

Same with 'break' - what if we have a switch in a loop? =) regards, frank
Jan 03 2008
prev sibling next sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
bearophile escribió:
 Bill Baxter:
 I'm no C# guy but that looks like a nice way to fix C's switch.

I think the C switch is broken in 2 or more ways, so I'd like to see D

 import std.stdio: writefln;
 void main(string[] args) {
   switch (args[1]) {
     int x = 1; // NOT initialized?
     case "1": writefln("1! x=", x); break;
     case "2": writefln("2! x=", x); break;
   }
 }

 More on switch-induced bugs:
 http://www.soft.com/AppNotes/attcrash.html


 "goto case 5" looks like something straight out of Walter's playbook, too.<

I don't like that goto too much... You usually just want do go down (and by

 But it's been discussed many times now and it doesn't seem likely Walter's 


 I agree with Walter when he says it's better that if a syntax that looks like 

looks different. Instead of switch{} it may be used caseof{}, plus the "default" statement, plus a new statement like "fall" (or something similar) that tells the compiler just to not break, so it's just the opposite of C :-)
 As example, this is a part of the std.string.capwords function:

 switch (s[i]) {
     case ' ':
     case '\t':
     case '\f':
     case '\r':
     case '\n':
     case '\v':
         if (inword) {
             r ~= capitalize(s[istart .. i]);
             inword = false;
         }
         break;

     default:
         if (!inword) {
             if (r.length)
             r ~= ' ';
             istart = i;
             inword = true;
         }
         break;
 }


 With that syntax it becomes:

 caseof (s[i]) {
     case ' ':  fall;
     case '\t': fall;
     case '\f': fall;
     case '\r': fall;
     case '\n': fall;
     case '\v':
         if (inword) {
             r ~= capitalize(s[istart .. i]);
             inword = false;
         }

     default:
         if (!inword) {
             if (r.length)
             r ~= ' ';
             istart = i;
             inword = true;
         }
 }

How about using existing D syntax? switch (s[i]) { case ' ', '\t', '\f', '\r', '\n', '\v': if (inword) { r ~= capitalize(s[istart .. i]); inword = false; } break; default: if (!inword) { if (r.length) r ~= ' '; istart = i; inword = true; } break; }
 D already follows such "inversion rule" regerding C in some cases, like here:

 int a = void;

 In a safe(r) language the default syntax/behavior *must* be the safer one, 

 Bye,
 bearophile

-- Carlos Santander Bernal
Jan 03 2008
parent reply S. <S s.com> writes:
Carlos Santander Wrote:
 
 How about using existing D syntax?
 
 switch (s[i]) {
       case ' ', '\t', '\f', '\r', '\n', '\v':
           if (inword) {
               r ~= capitalize(s[istart .. i]);
               inword = false;
           }
           break;
 
       default:
           if (!inword) {
               if (r.length)
               r ~= ' ';
               istart = i;
               inword = true;
           }
           break;
 }

This whole conversation about switch was kind of lost on me, but I have to contribute this. I, at various times, have written code that depends on case statements falling through, while not being identical! For example: switch(foo) { case 'bob': //Do bob stuff //Fall through and doo bar stuff too. case 'bar': //Do bar stuff and exit break; case 'baz': //Do some baz stuff break; } Whatever is changed shouldn't break this.
Jan 03 2008
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
S. wrote:

 This whole conversation about switch was kind of lost on me, 

Don't worry, none of it will ever happen in D, anyway.
 but I have to contribute this.
 I, at various times, have written code that depends on case statements falling
through, while not being identical!
 
 For example:
 
 switch(foo)
 {
 case 'bob':
     //Do bob stuff
     //Fall through and doo bar stuff too.
 case 'bar':
     //Do bar stuff and exit   
     break;
 
 case 'baz':
    //Do some baz stuff
    break;
 }
 
 Whatever is changed shouldn't break this.

Good news for you, then. Nothing's going to change! But man I wish it would, for 2.0 that is. I've been hit at least half-a-dozen times in the past year by missing break statements in my D code. And I have a C++ background! So it's not about familiarity. It bites me when I'm coding C++ just as frequently. It's simply a C/C++ mis-feature that D failed to correct. --bb
Jan 03 2008
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
S. Wrote:
 I, at various times, have written code that depends on case statements falling
through, while not being identical!

If you take a look at my original post, I have suggested to use a "fall" or "continue" statement when you want to go down, and nothing if you want the default of going at the end of the switch... Bye, bearophile
Jan 03 2008
parent reply S. <S s.com> writes:
bearophile Wrote:

 S. Wrote:
 I, at various times, have written code that depends on case statements falling
through, while not being identical!

If you take a look at my original post, I have suggested to use a "fall" or "continue" statement when you want to go down, and nothing if you want the default of going at the end of the switch... Bye, bearophile

The same problems you initially mentioned still exist in your proposal. You just moved them around: caseof(Foo) { case 'foo': writeflin("bar"); fall; x = 3; case 'bar': writefln("OMGWTF X != 3"); } Whatever complicated syntax you invent there will be unreachable code. The compiler should produce ERRORS on any unreachable code. The error you linked to is not switch-induced, but stupidity induced. However, I will say this: D is starting to become so complex that it is becoming difficult to understand the entire specification. Once it is no longer feasible to have the spec memorized then it becomes easy to make very silly mistakes. -S.
Jan 07 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
S:

The compiler should produce ERRORS on any unreachable code.<

I agree (D too has a simple way to spot dead code under a return in not-release mode). Sometimes Pascal syntax is better than the C one, the switch is one of them, I like the Pascal version better. In the Python community people collect use cases, do a simple frequency count of them, and then usually look for a simple solution able to cover most of them. So we can collect some use cases of the switch. I presume most use cases are covered by a Pascal-like syntax. The other situations are probably covered by putting commas between alternative cases. What other use cases do you people have?
The error you linked to is not switch-induced, but stupidity induced.<

Then the language (and language designers) must be twice intelligent to avoid errors done by "stupid" humans. Technology must adapt itself to the limits of the human brain, otherwise it's far more stupid than the humans. In this situation I think such adaptation doesn't require a more complex syntax or the usage or more CPU or more memory. A change has the disadvantage that it makes D syntax looking a bit less like C, and this may be a disadvantage.
However, I will say this:  D is starting to become so complex that it is
becoming difficult to understand the entire specification.   Once it is no
longer feasible to have the spec memorized then it becomes easy to make very
silly mistakes.<

I too like simpler languages better, that's why I like Python and D (D is simpler than C++ still) :-) D has many parts, so it's more complex than a language with less parts, but usually each D part has few interactions with all the other parts, so the actual complexity isn't too much high :-) Bye, bearophile
Jan 07 2008
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2008-01-07 20:48:54 -0500, bearophile <bearophileHUGS lycos.com> said:

 In the Python community people collect use cases, do a simple frequency 
 count of them, and then usually look for a simple solution able to 
 cover most of them. So we can collect some use cases of the switch. I 
 presume most use cases are covered by a Pascal-like syntax. The other 
 situations are probably covered by putting commas between alternative 
 cases. What other use cases do you people have?

A use case? I quite fancy GCC's extension which allows you to put ranges in case statements, for instance: switch (myChar) { case 'a'...'z': case 'A'...'Z': case '0'...'9': // do something. } I think D should have it too. (Also, since we're at it, it's covered by Pascal.) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 11 2008
parent reply Robert DaSilva <sp.unit.262+digitalmars gmail.com> writes:
Michel Fortin wrote:
 On 2008-01-07 20:48:54 -0500, bearophile <bearophileHUGS lycos.com> said:
 
 In the Python community people collect use cases, do a simple
 frequency count of them, and then usually look for a simple solution
 able to cover most of them. So we can collect some use cases of the
 switch. I presume most use cases are covered by a Pascal-like syntax.
 The other situations are probably covered by putting commas between
 alternative cases. What other use cases do you people have?

A use case? I quite fancy GCC's extension which allows you to put ranges in case statements, for instance: switch (myChar) { case 'a'...'z': case 'A'...'Z': case '0'...'9': // do something. } I think D should have it too. (Also, since we're at it, it's covered by Pascal.)

Yes, but it would be 'A' .. 'Z' not 'A' ... 'Z'.
Jan 11 2008
next sibling parent Daniel Lewis <murpsoft hotmail.com> writes:
Janice Caron Wrote:

 On 1/12/08, Robert DaSilva <sp.unit.262+digitalmars gmail.com> wrote:
 Yes, but it would be 'A' .. 'Z' not 'A' ... 'Z'.

In D parance, that would mean 'A' to 'Y' inclusive, but excluding 'Z'. (The three dot form could be used to mean "inclusive" though)

Not only; it would violate the 0..length meaning, and he also failed to recognize the syntax we've been pushing for to distinguish the new switch from the old. The new one looks like this: switch(x) { case(y) { } case (z) { } case (a) { } } Why? 1) It's more consistent with other structured D statements. 2) It differentiates it from the old way in our minds 3) It allows us to support both ways for a transition period. 4) The {} is syntactically associated with only affecting what's inside, while : is used to mean "everything after here" which is semantically correct. Regards, Dan
Jan 12 2008
prev sibling parent Jason House <jason.james.house gmail.com> writes:
Robert DaSilva wrote:

 Michel Fortin wrote:
 On 2008-01-07 20:48:54 -0500, bearophile <bearophileHUGS lycos.com> said:
 
 In the Python community people collect use cases, do a simple
 frequency count of them, and then usually look for a simple solution
 able to cover most of them. So we can collect some use cases of the
 switch. I presume most use cases are covered by a Pascal-like syntax.
 The other situations are probably covered by putting commas between
 alternative cases. What other use cases do you people have?

A use case? I quite fancy GCC's extension which allows you to put ranges in case statements, for instance: switch (myChar) { case 'a'...'z': case 'A'...'Z': case '0'...'9': // do something. } I think D should have it too. (Also, since we're at it, it's covered by Pascal.)

Yes, but it would be 'A' .. 'Z' not 'A' ... 'Z'.

That's always bugged me. Seems too easy for coding errors.
Jan 13 2008
prev sibling parent reply "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Fri, 04 Jan 2008 00:15:25 -0000, S. <S s.com> wrote:

 Carlos Santander Wrote:
 How about using existing D syntax?

 switch (s[i]) {
       case ' ', '\t', '\f', '\r', '\n', '\v':
           if (inword) {
               r ~=3D capitalize(s[istart .. i]);
               inword =3D false;
           }
           break;

       default:
           if (!inword) {
               if (r.length)
               r ~=3D ' ';
               istart =3D i;
               inword =3D true;
           }
           break;
 }

This whole conversation about switch was kind of lost on me, but I hav=

 to contribute this.

 I, at various times, have written code that depends on case statements=

 falling through, while not being identical!

 For example:

 switch(foo)
 {
 case 'bob':
     //Do bob stuff
     //Fall through and doo bar stuff too.
 case 'bar':
     //Do bar stuff and exit
     break;

 case 'baz':
    //Do some baz stuff
    break;
 }

 Whatever is changed shouldn't break this.

This whole conversation boggles me. cases should *never* fall through it= s = dangerous. Assuming polymorphism isn't the answer, which can often eliminate the = switch altogether its much cleaner, safer and better encapsulated in general to use a = function call to replace fall through. E.g. : handleBar() { //Do bar stuff } switch(foo) { case 'bob': // do bob stuff handleBar(); case 'bar': handleBar(); case 'baz': // do baz stuff } The switch can always compile to a simple look-up table that way.
Jan 03 2008
parent reply S. <S s.com> writes:
Bruce Adams Wrote:

 On Fri, 04 Jan 2008 00:15:25 -0000, S. <S s.com> wrote:
 
 Carlos Santander Wrote:
 How about using existing D syntax?

 switch (s[i]) {
       case ' ', '\t', '\f', '\r', '\n', '\v':
           if (inword) {
               r ~= capitalize(s[istart .. i]);
               inword = false;
           }
           break;

       default:
           if (!inword) {
               if (r.length)
               r ~= ' ';
               istart = i;
               inword = true;
           }
           break;
 }

This whole conversation about switch was kind of lost on me, but I have to contribute this. I, at various times, have written code that depends on case statements falling through, while not being identical! For example: switch(foo) { case 'bob': //Do bob stuff //Fall through and doo bar stuff too. case 'bar': //Do bar stuff and exit break; case 'baz': //Do some baz stuff break; } Whatever is changed shouldn't break this.

This whole conversation boggles me. cases should *never* fall through its dangerous.

In other news, it has been discovered that the risk of choking is greatly increased by eating anything that is not pureed. As a result, lawmakers have outlawed solid food. Programming requires a brain. You should go read DailyWTF for awhile. It is possible to do the most ridiculous things no matter how carefully the language is crafted. We should just stay away from hand-holding and focus on making things easier. I agree with measures that make debugging easier when dealing with naming and hijacking. However, a simple step-through will reveal a case falling through when it shouldn't. The aforementioned issues are not as easily caught. -S.
Jan 07 2008
next sibling parent reply "Bruce Adams" <tortoise_74 yeah.who.co.uk> writes:
On Mon, 07 Jan 2008 22:51:31 -0000, S. <S s.com> wrote:

 Bruce Adams Wrote:

 On Fri, 04 Jan 2008 00:15:25 -0000, S. <S s.com> wrote:

 Carlos Santander Wrote:
 How about using existing D syntax?

 switch (s[i]) {
       case ' ', '\t', '\f', '\r', '\n', '\v':
           if (inword) {
               r ~=3D capitalize(s[istart .. i]);
               inword =3D false;
           }
           break;

       default:
           if (!inword) {
               if (r.length)
               r ~=3D ' ';
               istart =3D i;
               inword =3D true;
           }
           break;
 }

This whole conversation about switch was kind of lost on me, but I =



 have
 to contribute this.

 I, at various times, have written code that depends on case stateme=



 falling through, while not being identical!

 For example:

 switch(foo)
 {
 case 'bob':
     //Do bob stuff
     //Fall through and doo bar stuff too.
 case 'bar':
     //Do bar stuff and exit
     break;

 case 'baz':
    //Do some baz stuff
    break;
 }

 Whatever is changed shouldn't break this.

This whole conversation boggles me. cases should *never* fall through=


 its
 dangerous.

In other news, it has been discovered that the risk of choking is =

 greatly increased by eating anything that is not pureed.  As a result,=

 lawmakers have outlawed solid food.

(http://en.wikipedia.org/wiki/Ignoratio_elenchi) Lawmakers never actually outlawed goto but you don't see it used very = often. That's because putting glass in your food is not a good idea.
 Programming requires a brain.

= development. Fall through unnecessarily complicates things without adding much if = indeed any power. I'd rather use my brain on the important things.
 You should go read DailyWTF for awhile.  It is possible to do the most=

 ridiculous things no matter how carefully the language is crafted.  We=

 should just stay away from hand-holding and focus on making things  =

 easier.

= easier to write safe code?
 I agree with measures that make debugging easier when dealing with  =

 naming and hijacking.  However, a simple step-through will reveal a ca=

 falling through when it shouldn't.  The aforementioned issues are not =

 easily caught.

= easy enough to find the source and targets of a goto with a find in your code. Okay its= = nowhere near in the same league as goto but the point's still valid.
 -S.

B. -- = Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jan 07 2008
parent S. <S s.com> writes:
Bruce Adams Wrote:

 On Mon, 07 Jan 2008 22:51:31 -0000, S. <S s.com> wrote:
 
 Bruce Adams Wrote:

 On Fri, 04 Jan 2008 00:15:25 -0000, S. <S s.com> wrote:

 Carlos Santander Wrote:
 How about using existing D syntax?

 switch (s[i]) {
       case ' ', '\t', '\f', '\r', '\n', '\v':
           if (inword) {
               r ~= capitalize(s[istart .. i]);
               inword = false;
           }
           break;

       default:
           if (!inword) {
               if (r.length)
               r ~= ' ';
               istart = i;
               inword = true;
           }
           break;
 }

This whole conversation about switch was kind of lost on me, but I

 to contribute this.

 I, at various times, have written code that depends on case statements
 falling through, while not being identical!

 For example:

 switch(foo)
 {
 case 'bob':
     //Do bob stuff
     //Fall through and doo bar stuff too.
 case 'bar':
     //Do bar stuff and exit
     break;

 case 'baz':
    //Do some baz stuff
    break;
 }

 Whatever is changed shouldn't break this.

This whole conversation boggles me. cases should *never* fall through its dangerous.

In other news, it has been discovered that the risk of choking is greatly increased by eating anything that is not pureed. As a result, lawmakers have outlawed solid food.

(http://en.wikipedia.org/wiki/Ignoratio_elenchi) Lawmakers never actually outlawed goto but you don't see it used very often. That's because putting glass in your food is not a good idea.

Well one probably not. For one, there isn't a formal definition given for that term on your cited page. Secondly, my point is that most things that are generic enough to be useful, are inherently dangerous if misused. Consider most kitchen utensils. The ones that are "safe" only do one thing, and if you want a "safe" kitchen then you need hundreds of these gadgets. goto, and break, are defined in such general terms that they are useful over a wide range of constructs. If you want to make things "safe" you need to pollute your "kitchen" with gadgets. I would like to see the specification stay simple enough that know what exactly each "tool" does in a general sense and then apply it in a specific way. Now sometimes, if something is used enough, then it makes sense to have a special tool for it. (Like having a coffee pot instead of just boiling grounds and straining them out later.) This is why I like D instead of just straight up C.
 Programming requires a brain.

development. Fall through unnecessarily complicates things without adding much if indeed any power. I'd rather use my brain on the important things.

And calling into another function in order to duplicate functionality requires introduce a new scope.... If the specification is easily understood then there isn't much problem here...
 You should go read DailyWTF for awhile.  It is possible to do the most  
 ridiculous things no matter how carefully the language is crafted.  We  
 should just stay away from hand-holding and focus on making things  
 easier.

easier to write safe code?

It should be easier to write safe code, and easier to debug and easier to read. Sometimes though, the compiler should just warn you when you're using a construct incorrectly. For example, a return statement can cause unreachable code. Should we get rid of the return statement in favor of 15 different keywords to do similar (but specific) things, or make it an error when it produces unreachable code? I think my take on how I run my kitchen is applicable to D.
 
 I agree with measures that make debugging easier when dealing with  
 naming and hijacking.  However, a simple step-through will reveal a case  
 falling through when it shouldn't.  The aforementioned issues are not as  
 easily caught.

easy enough to find the source and targets of a goto with a find in your code. Okay its nowhere near in the same league as goto but the point's still valid.

By aforementioned issues I meant hijacking and protection levels. Which are basically the same reason we require our variables to be defined instead of just implying them when they're used. Is the trade off of having to declare your variables worth not having to figure out what is going on when you mistype a variable name? Yes, most certainly. I don't think switch, goto, break, and the like are anything like that. -S.
Jan 07 2008
prev sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
S. wrote:

 However, a simple step-through will reveal a case falling through when it
shouldn't.

Eliminating the possibility of unintentional fall-through altogether will eliminate the need for even your "simple step-through". And simple step through may not be so simple when the program is hundreds of thousands of lines long. Mistaken fall-through in some switch in some function in some module can change a state, and that state can later trigger another different change of state and so on, until finally somewhere your program crashes because of an incorrect state a dozen causal steps away from the original problem. So "simple step through" may mean "simply" stepping through thousands of lines of code to try to figure out where things first went wrong. It can be very non-trivial. Implicit switch fall-through is evil. --bb
Jan 07 2008
prev sibling next sibling parent reply James Dennett <jdennett acm.org> writes:
bearophile wrote:
 Bill Baxter:
 I'm no C# guy but that looks like a nice way to fix C's switch.

I think the C switch is broken in 2 or more ways, so I'd like to see D improve it. This is some code I have shown time ago: import std.stdio: writefln; void main(string[] args) { switch (args[1]) { int x = 1; // NOT initialized? case "1": writefln("1! x=", x); break; case "2": writefln("2! x=", x); break; } }

C++ fixed this some time in the last century, making the code above ill-formed (diagnostic required) as it skips the initialization of x. (It's still UB in C99 so far as I know.) -- James
Jan 04 2008
parent Bill Baxter <dnewsgroup billbaxter.com> writes:
James Dennett wrote:
 bearophile wrote:
 Bill Baxter:
 I'm no C# guy but that looks like a nice way to fix C's switch.

import std.stdio: writefln; void main(string[] args) { switch (args[1]) { int x = 1; // NOT initialized? case "1": writefln("1! x=", x); break; case "2": writefln("2! x=", x); break; } }

C++ fixed this some time in the last century, making the code above ill-formed (diagnostic required) as it skips the initialization of x. (It's still UB in C99 so far as I know.)

That's actually in the spec? Cool. I thought it was just a QOI thing. --bb
Jan 04 2008
prev sibling next sibling parent Robert DaSilva <sp.unit.262+digitalmars gmail.com> writes:
I just noticed this in the specs.
"The third form, goto case;, transfers to the next CaseStatement of the
innermost enclosing SwitchStatement."
Jan 11 2008
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 1/12/08, Robert DaSilva <sp.unit.262+digitalmars gmail.com> wrote:
 Yes, but it would be 'A' .. 'Z' not 'A' ... 'Z'.

In D parance, that would mean 'A' to 'Y' inclusive, but excluding 'Z'. (The three dot form could be used to mean "inclusive" though)
Jan 12 2008