Make switch statement safe by default

527 views
Skip to first unread message

atch...@gmail.com

unread,
Nov 9, 2012, 12:11:28 PM11/9/12
to std-dis...@isocpp.org
There is well known problem with the switch statement in C++ - if you don't write break it will follow up to the next case which is very often cause of hard to find, very subtle bugs. I propose to introduce rule that says:

"If there is nothing after switch keyword, then the behavior of this construct is as if at the end of every case: the break keyword had been put" 

This would:
a) not break any existing code
b) help to find hidden/subtle, bugs (due to the omission by a programmer 'break' at the end of some case)
c) help to write "safe" out of box switch with identical syntax

This would require:
a) in case there is a need for actually needing the cases to follow from one to another (very rare case I believe) then there is a following proposition for a slightly modified syntax:

switch[follow](variable)//here I have the new "keyword" follow to indicate that this switch statement will follow from one case into another
{
//nothing changes here
}

on the other hand if the "regular" behavior is needed (break after each case) nothing changes to the syntax:

switch(variable)
{
//nothing changes here
}

the above code should be interpreted as:

switch[break](variable)//where break keyword indicates that it will be automatically inserted at the end of each case
{
//nothing changes here
}
Looking forward to your opinions

Chris Jefferson

unread,
Nov 9, 2012, 12:20:09 PM11/9/12
to std-dis...@isocpp.org
On 09/11/12 17:11, atch...@gmail.com wrote:
> There is well known problem with the switch statement in C++ - if you
> don't write break it will follow up to the next case which is very
> often cause of hard to find, very subtle bugs. I propose to introduce
> rule that says:
>
> "If there is nothing after switch keyword, then the behavior of this
> construct is as if at the end of every case: the break keyword had
> been put"
>
> This would:
> a) not break any existing code

Wait, are you planning on changing the default switch, or not? While I
agree that switch statements can be tricky to write
, if you are planning to change switch statements written in the current
standard fashion, then you will break a huge amount of code, completely
silently. That is (in my opinion), completely unacceptable. Sorry.
Falling through switch statements is, I think, more common than you
might expect. I have certainly written many, and would be annoyed beyond
belief if all that code just broke.

Chris

Ville Voutilainen

unread,
Nov 9, 2012, 12:20:49 PM11/9/12
to std-dis...@isocpp.org
On 9 November 2012 19:11, <atch...@gmail.com> wrote:
> There is well known problem with the switch statement in C++ - if you don't
> write break it will follow up to the next case which is very often cause of
> hard to find, very subtle bugs. I propose to introduce rule that says:
> "If there is nothing after switch keyword, then the behavior of this
> construct is as if at the end of every case: the break keyword had been put"
> Looking forward to your opinions

I have written new switch constructs with lambdas, aka with a pure
library solution.
The syntax isn't 1-to-1 identical with a switch, but it's close enough
for me. I don't
expect non-experts to be able to do that, though, so having an easier solution
for the problem would be nice. I don't much like the switch[break] syntax, but I
don't have a better idea on the top of my head right now.

atch...@gmail.com

unread,
Nov 9, 2012, 12:27:13 PM11/9/12
to std-dis...@isocpp.org
Wait, are you planning on changing the default switch, or not? While I
agree that switch statements can be tricky to write

Hi, I believe that the existence of 'case:' in switch statement indicates that there is a certain case for a certain value, so I'd like to hear others and asses how much of their switch statements is intentionally written with follow through option. I personally believe that this is rather rare, and (sorry) bad practice.

The switch statement proposed by me would have the default option (no changes to the existing syntax) to have break at the end of each case

Regards

atch...@gmail.com

unread,
Nov 9, 2012, 12:30:28 PM11/9/12
to std-dis...@isocpp.org
I have certainly written many, and would be annoyed beyond
belief if all that code just broke.

With the new rule I propose you'd have to write:

switch[follow](value)
{
//nothing changes here
}

by doing so you'd create self-documented code and your intentions would be clear and unambiguous. No other person checking the code after you would wonder if you forgot to put break or if it is intentional.


On Friday, 9 November 2012 17:20:12 UTC, Chris Jefferson wrote:

Ville Voutilainen

unread,
Nov 9, 2012, 12:31:41 PM11/9/12
to std-dis...@isocpp.org
On 9 November 2012 19:30, <atch...@gmail.com> wrote:
>> I have certainly written many, and would be annoyed beyond
>> belief if all that code just broke.
> With the new rule I propose you'd have to write:
> switch[follow](value)
> {
> //nothing changes here
> }
> by doing so you'd create self-documented code and your intentions would be
> clear and unambiguous. No other person checking the code after you would
> wonder if you forgot to put break or if it is intentional.

So you _are_ proposing a change to existing switch. That breaks so
much existing code that
it is indeed completely unacceptable.

atch...@gmail.com

unread,
Nov 9, 2012, 12:32:48 PM11/9/12
to std-dis...@isocpp.org
Only breaks code which is written in poor style. Correctly written code isn't broken.

Ville Voutilainen

unread,
Nov 9, 2012, 12:34:08 PM11/9/12
to std-dis...@isocpp.org
On 9 November 2012 19:32, <atch...@gmail.com> wrote:
> Only breaks code which is written in poor style. Correctly written code
> isn't broken.

The code broken is every bit as _correctly written_ as can be. The standard
is not a style guide, and we are not going to make such a breaking change.

Howard Hinnant

unread,
Nov 9, 2012, 12:41:21 PM11/9/12
to std-dis...@isocpp.org
On Nov 9, 2012, at 9:27 AM, atch...@gmail.com wrote:

> Hi, I believe that the existence of 'case:' in switch statement indicates that there is a certain case for a certain value, so I'd like to hear others and asses how much of their switch statements is intentionally written with follow through option. I personally believe that this is rather rare, and (sorry) bad practice.
>

I just surveyed code which I consider myself the principle owner of for drop-through cases. Their occurrence is rather rare. In approximately 700 cases, only 3 were drop-through (identified by comments put in for that purpose). I don't know if my code is representative. I do know that although 3/700 might seem rare, it is far too common for a silently breaking change.

I too wish the default were break, and that an explicit keyword (e.g. continue) be required to drop through. But the decision on this design was made decades ago and doesn't seem like the sort of thing that can easily be changed at this point without silently breaking massive amounts of code.

As for whether or not it is bad practice to write a drop-through case, I don't really want to, nor have time to, get into that discussion. Feel free to peruse the code and decide for yourself, and even propose patches for this public source code:

http://libcxx.llvm.org
http://libcxxabi.llvm.org

Howard

Howard Hinnant

unread,
Nov 9, 2012, 12:50:43 PM11/9/12
to std-dis...@isocpp.org
Oh, I should've warned code reviewers: there's also a few uses of goto scattered throughout. I really am incorrigible.

Howard

Chris Jefferson

unread,
Nov 9, 2012, 12:52:19 PM11/9/12
to std-dis...@isocpp.org
On 09/11/12 17:32, atch...@gmail.com wrote:
Only breaks code which is written in poor style. Correctly written code isn't broken.

I will say I agree that back when switch statements were originally invented, it would fixed a lot of pain for many people if each section had to be finished with (say) either a "break;" statement, or a "fallthrough;" statement.

However, at this point it is far too late, and there is far too much code in existence, for anyone to decide such code is "poorly written", and will have it's behaviour silently changed. In general, no change to the C++ standard which silently changed the behaviour of so much code would ever be accepted, and if it was none of the compilers would ever implement it. The C++ standard does not live in a vacuum, there are millions of lines of code out there, already written and happily running away. Imagine just having to go and check every 'switch' statement in gcc, or firefox, to make sure they are 'well written'. Also this would make it hard to write code that worked in both C++11 and C++14 (or whichever later version existed), and also co-exist C and C++ code.

If you really feel that strongly about switch statements, there are perhaps some more achievable routes. I am not as expert in attributes as I would like, but it should be possible to use attributes to mark switch statements as not having any fallthroughs, and then warning in the compiler if such cases exist.

If you feel so strongly about this, there are other options,

clang has a warning flag (-Wimplicit-fallthrough) which checks for this very case, which can be disabled for a particular case statement using the attribute [[clang::fallthrough]];. gcc has a very long standing bug ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7652) which covers adding this warning to gcc which no-one has ever bothered implementing. Implementing this warning to gcc would give this issue more visibility.

Personally I never compile without warnings turned on, if this [[fallthrough]] attribute was widely implemented, there is a good chance it could be standardised (or if everyone implemented it, it would be effectively standardised anyway). While this wouldn't lead to a change in behaviour, the obvious warning should point out people's mistakes.

Chris


On Friday, 9 November 2012 17:31:44 UTC, Ville Voutilainen wrote:
On 9 November 2012 19:30,  <atch...@gmail.com> wrote:
>> I have certainly written many, and would be annoyed beyond
>> belief if all that code just broke.
> With the new rule I propose you'd have to write:
> switch[follow](value)
> {
> //nothing changes here
> }
> by doing so you'd create self-documented code and your intentions would be
> clear and unambiguous. No other person checking the code after you would
> wonder if you forgot to put break or if it is intentional.

So you _are_ proposing a change to existing switch. That breaks so
much existing code that
it is indeed completely unacceptable.
--
 
 
 

Nicol Bolas

unread,
Nov 9, 2012, 1:00:18 PM11/9/12
to std-dis...@isocpp.org
It should also be noted that many languages have adopted C-style switch statements including C-style default fall-through. For C++ to change the default, even ignoring the millions of programs that would suddenly break in unpleasant ways, would be an extremely surprising thing for many programmers.

atch...@gmail.com

unread,
Nov 10, 2012, 5:22:43 AM11/10/12
to std-dis...@isocpp.org
Hi Chris

Thank you for your reply.

As Howard noted, those follow-through cases are rare, maybe others disagree, maybe others have different experience. I'd like to hear that. From my own experience I clearly remember that I had used follow-through once and that's it. So I also believe that the case of follow-through is rare and in most cases is simply an error.

My proposal doesn't have to break things silently though. The compiler can emit warning that there are unmarked switch statements with follow-through cases, this warning can be treated as an error if you wish so.

The whole point here (I believe) is to make C++ safe to use, and give some tool to the programmer to protect against such mistakes.

I personally I'm quite skeptical about the "never break my code" rule. As Dave Abrahams pointed out, some code was consiously broken by C++11 and most likely will be broken by C++14/17. Sometimes old, bad things need to be broken in order for new ones to flourish. I believe no-one doubts the benefits of safe switch. If so, don't break my code simply doesn't do the trick for me.

Regards

atch...@gmail.com

unread,
Nov 10, 2012, 5:58:53 AM11/10/12
to std-dis...@isocpp.org
Nicol

For C++ to change the default, even ignoring the millions of programs that would suddenly break in unpleasant ways, would be an extremely surprising thing for many programmers.

As has been noted the follow-through cases are very rare (less than 0.5%), add the margin of 3% to it and you have <5% of cases. How many of them are genuine? And how many of them are hidden/hard to find bugs? I genuinely believe that having some tool which would help the programmer write safe and easy to understand code is a good thing.

Ville Voutilainen

unread,
Nov 10, 2012, 7:00:50 AM11/10/12
to std-dis...@isocpp.org
On 10 November 2012 12:58, <atch...@gmail.com> wrote:
> As has been noted the follow-through cases are very rare (less than 0.5%),
> add the margin of 3% to it and you have <5% of cases. How many of them are
> genuine? And how many of them are hidden/hard to find bugs? I genuinely

Most, if not all of them are "genuine". The ones mentioned by Howard most
certainly are. Every occurrence of a Duff's device is "genuine", and all of
them would be broken.

> believe that having some tool which would help the programmer write safe and
> easy to understand code is a good thing.

Static analyzers like pc-lint already provide such a tool.

Daniel Krügler

unread,
Nov 10, 2012, 7:01:08 AM11/10/12
to std-dis...@isocpp.org
2012/11/10 <atch...@gmail.com>

As has been noted the follow-through cases are very rare (less than 0.5%), add the margin of 3% to it and you have <5% of cases. How many of them are genuine? And how many of them are hidden/hard to find bugs? I genuinely believe that having some tool which would help the programmer write safe and easy to understand code is a good thing.

Let me throw my 2 Euro cents in here: The semantics of the switch selection exists since decades and
is a rule that is not a bug in the sense "Uhm, yeah, we never noticed that - lets fix it".

"Falling-through" cases *are* used intentionally in the wild and any arguments based on whether the usage percentage is 0.5% or even only 0.05% is not a good criterion to decide to change a *well-defined* specification.

I'm not aware of any compiler that does not implement switch correctly and I have never heard of whether the wording can be interpreted in different ways. These would be other reasonable arguments to present in that context.

This means that the resistance of a change that would change the effects of well-defined programs
silently will be extremely high. Personally I would say: so high that the chance of accepting such a change is
near to zero.

If you want to improve the switch specification this really must be done by inventing a currently impossible
syntax, either by "decorating" the switch statement somehow or inventing new "case" keywords.

I don't want to discourage you to help improving the language. But you really must keep in mind that such a Standard specification will always have a ensure that existing, valid programs will not change or at least not silently.

- Daniel




Daniel Krügler

unread,
Nov 10, 2012, 7:11:04 AM11/10/12
to std-dis...@isocpp.org
2012/11/10 Daniel Krügler <daniel....@gmail.com>

And I would also like to add that there exists a small number of cases where there was deviated from this paradigm, especially to mention are the move constructors and move assignment operators as special members.

Nonetheless these changes were debated for quite a while and this decision was not an easy one. In regard to your proposal to change switch statements I have a hard time to still argue in favor of such a change, because it is simply the fact that several programming idioms intentionally take advantage of exactly this fall-through semantics.
 

- Daniel





Loïc Joly

unread,
Nov 10, 2012, 7:14:57 AM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com
Le 10/11/2012 11:58, atch...@gmail.com a �crit :
> Nicol
>
> For C++ to change the default, even ignoring the millions of
> programs that would suddenly break in unpleasant ways, would be an
> extremely surprising thing for many programmers.
>
>
> As has been noted the follow-through cases are very rare (less than
> 0.5%), add the margin of 3% to it and you have <5% of cases. How many
> of them are genuine? And how many of them are hidden/hard to find
> bugs? I genuinely believe that having some tool which would help the
> programmer write safe and easy to understand code is a good thing.

I disagree with your mathematics.
Even if a concious fall-through is very rare (say, for the sake of
discussion, 0.1% of the cases), a typical program, with several million
LOC probably contains more than 1000 switch. Which means that even with
a low occurrence of fall-through, such a change may very well just break
every program on the planet.

I also disagree with your hypothesis that most of those cases are not
genuine. They are present in working code, and I guess that most of the
wrong cases have been debugged at one time or another. The proportion of
cases where this is made on purpose is probably higher in old code than
in very recent code. And your change would break that code.

I agree that everything that can help should be studied. You used the
term "having some tool". I think that in this case, the right tool for
the task might not be a change in the language, but for instance a
static analysis tool that warns you about a strange code, but does not
silently changes the meaning of your existing and working code.

--
Lo�c

Loïc Joly

unread,
Nov 10, 2012, 7:21:10 AM11/10/12
to std-dis...@isocpp.org, Daniel Krügler
Le 10/11/2012 13:01, Daniel Kr�gler a �crit :
>
> If you want to improve the switch specification this really must be
> done by inventing a currently impossible
> syntax, either by "decorating" the switch statement somehow or
> inventing new "case" keywords.

I'm thinking about that, and I think that maybe the attribute syntax
could be used here. An attribute could be added to a case to specify
that the fall-through is intentional. And static analysis tools would
use this attribute to reduce the number of false positives to their
diagnostics.

Standardizing this attribute would have the benefit of compatibility
between static analysis tools, while respecting the agreement that
standard attribute should not change the meaning of a correct program.
I'm however not 100% sure if this is worth it.

--
Lo�c

Daniel Krügler

unread,
Nov 10, 2012, 7:39:59 AM11/10/12
to Loïc Joly, std-dis...@isocpp.org
2012/11/10 Loïc Joly <loic.act...@numericable.fr>
I agree that this would be a possible use-case of attributes. Personally I don't think that it is worth the effort
standardizing it.

I have a different suggestion in regard to switch statements (And I think this is no the first time it has been suggested), namely to allow a single case statement to accept a range of values (This is what Pascal allows, for example), e.g.

switch (whatever) {
case 1..10:
  break;
case 11..20:
  break;
case 30, 35, 40:
}

This is completely orthogonal to Arthur's proposal and I apologize for silently moving the center of this discussion, but this would IMO be very helpful.

- Daniel

Jean-Marc Bourguet

unread,
Nov 10, 2012, 8:01:56 AM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com
Fall-through cases are far more common than you hint and they are wanted:
switch(foo) {
case bar: case qux:
   
// do something
   
break;
default:
   
// do something else
   
break;
}

You at the very least need to be able to handle that case (it's probably not hard, but it needs to be done). If you drop the idea of changing the semantic of existing code (see below), you can have an alternative case syntax, perhaps taking the opportunity to standardize and expand the case range extension of GCC, something like:
switch (foo) {
case bar, qux...quux:
   
// do something
default:
   
// do something else
}

I'd strongly suggest to drop the idea of changing the semantic of existing code. C++ is more than 30 years old, and share a common subset with C, and you may think what you want about the soundness of the approach, some are purposefully using that subset. The part you want to change is just there: present in C++ since day one and shared with C, you'd need very good arguments to reduce the common subset and if removing that wart was enough to justify the change, my guess is that it would have already been done.

Yours,

--
Jean-Marc

Christof Meerwald

unread,
Nov 10, 2012, 8:11:23 AM11/10/12
to std-dis...@isocpp.org
On Sat, Nov 10, 2012 at 01:39:59PM +0100, Daniel Krügler wrote:
> I have a different suggestion in regard to switch statements (And I think
> this is no the first time it has been suggested), namely to allow a single
> case statement to accept a range of values (This is what Pascal allows, for
> example), e.g.
>
> switch (whatever) {
> case 1..10:
> break;
> case 11..20:
> break;
> case 30, 35, 40:
> }

Maybe allow the use of an initializer-list in the case label - and
also come up with a way to specify a range of values in an
initializer-list (which might be useful in other contexts as well).


Christof

--

http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

Christof Meerwald

unread,
Nov 10, 2012, 11:50:52 AM11/10/12
to std-dis...@isocpp.org
On Sat, Nov 10, 2012 at 02:11:23PM +0100, Christof Meerwald wrote:
> On Sat, Nov 10, 2012 at 01:39:59PM +0100, Daniel Krügler wrote:
> > switch (whatever) {
> > case 1..10:
> > break;
> > case 11..20:
> > break;
> > case 30, 35, 40:
> > }
>
> Maybe allow the use of an initializer-list in the case label - and
> also come up with a way to specify a range of values in an
> initializer-list (which might be useful in other contexts as well).

Hmm, what about making 1..10 an integral pack literal (?) and then you
could expand that, e.g.

case { 1..10 ... }:

but that would also be useful in other contexts, e.g.

constexpr int foo(int x)
{ return x*x; }

int arr1[] = { 1..10 ... };
int arr2[] = { foo(1..10) ... };

Nicol Bolas

unread,
Nov 10, 2012, 12:15:48 PM11/10/12
to std-dis...@isocpp.org, Daniel Krügler
I'm with Herb Sutter on attributes: they should never affect language semantics. We should not use attributes as a cheap method of getting keywords.

On Saturday, November 10, 2012 4:21:12 AM UTC-8, Loïc Joly wrote:
Le 10/11/2012 13:01, Daniel Kr�gler a �crit :
Lo�c

Ville Voutilainen

unread,
Nov 10, 2012, 12:18:05 PM11/10/12
to std-dis...@isocpp.org
On 10 November 2012 19:15, Nicol Bolas <jmck...@gmail.com> wrote:
> I'm with Herb Sutter on attributes: they should never affect language
> semantics. We should not use attributes as a cheap method of getting
> keywords.

What Loic suggests doesn't yield a semantic effect.

Nicol Bolas

unread,
Nov 10, 2012, 12:26:04 PM11/10/12
to std-dis...@isocpp.org

While Loic's post focuses on static analysis tools, the attribute would have to have effects on compiler-generated output messages and compilation in general. That's generally the first stop when dealing with this stuff.

The thing the OP wants is to make it illegal for the standard switch/case statement to fall-through without some special syntax to say that the fall-through is deliberate. Loic proposed that the special syntax be an attribute. That sounds like a semantic effect to me.

Ville Voutilainen

unread,
Nov 10, 2012, 12:32:10 PM11/10/12
to std-dis...@isocpp.org
On 10 November 2012 19:26, Nicol Bolas <jmck...@gmail.com> wrote:
>> What Loic suggests doesn't yield a semantic effect.
> While Loic's post focuses on static analysis tools, the attribute would have
> to have effects on compiler-generated output messages and compilation in
> general. That's generally the first stop when dealing with this stuff.
> The thing the OP wants is to make it illegal for the standard switch/case
> statement to fall-through without some special syntax to say that the
> fall-through is deliberate. Loic proposed that the special syntax be an
> attribute. That sounds like a semantic effect to me.

Loic suggested an alternative, which is a standard attribute to tell the static
analyzers to shut up when they see this intentional fall-through. He didn't
propose an attribute that has a semantic effect.

atch...@gmail.com

unread,
Nov 10, 2012, 12:33:09 PM11/10/12
to std-dis...@isocpp.org
The thing the OP wants is to make it illegal 
Nicol, I didn't say illegal. I meant that the default behavior would be to have implicit break at the end of each case.

Daniel Krügler

unread,
Nov 10, 2012, 12:33:27 PM11/10/12
to std-dis...@isocpp.org
2012/11/10 Nicol Bolas <jmck...@gmail.com>



On Saturday, November 10, 2012 9:18:06 AM UTC-8, Ville Voutilainen wrote:
On 10 November 2012 19:15, Nicol Bolas <jmck...@gmail.com> wrote:
> I'm with Herb Sutter on attributes: they should never affect language
> semantics. We should not use attributes as a cheap method of getting
> keywords.

What Loic suggests doesn't yield a semantic effect.

While Loic's post focuses on static analysis tools, the attribute would have to have effects on compiler-generated output messages and compilation in general. That's generally the first stop when dealing with this stuff.

"would have to have effects on compiler-generated output messages and compilation in general" is a little bit fuzzy and as written would not conflict with attribute-control. The litmus-test is: Would there be a different compile-time acceptance or runtime-behaviour when the attribute is ignored or not?


When Loic wrote:

"An attribute could be added to a case to specify that the fall-through is intentional. And static analysis tools would use this attribute to reduce the number of false positives to their diagnostics"

I think that it is clear that with or without the attribute the code would be same and the program would be accepted in the same way. The only difference would be for static tools to respect this marker as "This fall-through is intended, please don't warn me".

- Daniel

 

atch...@gmail.com

unread,
Nov 10, 2012, 12:55:30 PM11/10/12
to std-dis...@isocpp.org
Hi Daniel

Thank you for your reply. Actually the more I think about it the more I don't like my proposal. Why? Because I don't like when things are implicit. To me, best solution is: If you can't see it - it's not there. So in other words, some responsibility from a programmer must be expected.
There is one more possibility, which could be considered:

switch(v)
{
using 1:
using 2:
using 3:
}

As you can see, existing keyword is used, and the meaning is clear: if there is v == 1 use 1, etc. without falling through of course.

Regards

Daniel Krügler

unread,
Nov 10, 2012, 1:02:02 PM11/10/12
to std-dis...@isocpp.org
2012/11/10 <atch...@gmail.com>

Hi Daniel

Thank you for your reply. Actually the more I think about it the more I don't like my proposal. Why? Because I don't like when things are implicit. To me, best solution is: If you can't see it - it's not there. So in other words, some responsibility from a programmer must be expected.
There is one more possibility, which could be considered:

switch(v)
{
using 1:
using 2:
using 3:
}

As you can see, existing keyword is used, and the meaning is clear: if there is v == 1 use 1, etc. without falling through of course.

Yes, this would be an acceptable, non-breaking solution of your idea.

- Daniel

atch...@gmail.com

unread,
Nov 10, 2012, 1:10:11 PM11/10/12
to std-dis...@isocpp.org
Hi

Thank you.

I'd like to also allow for something like this: (because I do believe non-repetition is important)

switch(v)
{
using 1,3://here I'm combining those values for which behavior should be identical whilst avoiding unnecessary repetition.
using 2:
}

I also proposed earlier on general syntax for using declaration to allow multiple entries and that would be simply following that rule.

Regards

Nicol Bolas

unread,
Nov 10, 2012, 1:28:15 PM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com


On Saturday, November 10, 2012 10:10:12 AM UTC-8, atch...@gmail.com wrote:
Hi

Thank you.

I'd like to also allow for something like this: (because I do believe non-repetition is important)

switch(v)
{
using 1,3://here I'm combining those values for which behavior should be identical whilst avoiding unnecessary repetition.
using 2:
}

I also proposed earlier on general syntax for using declaration to allow multiple entries and that would be simply following that rule.

The use of the comma there could be troublesome, parser-wise. After all, case statements use expressions (compile-time constant ones), which can include the comma operator.

Also, there could be some issue with using, um, `using` in this context. I honestly don't know what the rules are in C++ with respect to parsing these sorts of things, but it's possible that:

constexpr int val = 5;

switch(...)
{
 
using val:
...
 
using val; //<-- not a colon.
...
}

This might be a problem. It might not. But you'd need to find out before making a real proposal.

Message has been deleted

atch...@gmail.com

unread,
Nov 10, 2012, 1:41:56 PM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com
Hi Nicol

Yes, you definitely have a point. Thank you for your input. Must think about it as this is real issue.

Nevin Liber

unread,
Nov 10, 2012, 3:21:09 PM11/10/12
to std-dis...@isocpp.org
On 10 November 2012 06:00, Ville Voutilainen <ville.vo...@gmail.com> wrote:
On 10 November 2012 12:58,  <atch...@gmail.com> wrote:
> As has been noted the follow-through cases are very rare (less than 0.5%),
> add the margin of 3% to it and you have <5% of cases. How many of them are
> genuine? And how many of them are hidden/hard to find bugs? I genuinely

Most, if not all of them are "genuine". The ones mentioned by Howard most
certainly are. Every occurrence of a Duff's device is "genuine", and all of
them would be broken.

And there is the common pattern:

case 1:
case 2:
case 3:
    DoSomething();
    break;

which is technically fall though for case 1 and case 2.
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

Daniel Krügler

unread,
Nov 10, 2012, 3:37:59 PM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com
2012/11/10 Nicol Bolas <jmck...@gmail.com>

On Saturday, November 10, 2012 10:10:12 AM UTC-8, atch...@gmail.com wrote:
Hi

Thank you.

I'd like to also allow for something like this: (because I do believe non-repetition is important)

switch(v)
{
using 1,3://here I'm combining those values for which behavior should be identical whilst avoiding unnecessary repetition.
using 2:
}

I also proposed earlier on general syntax for using declaration to allow multiple entries and that would be simply following that rule.

The use of the comma there could be troublesome, parser-wise. After all, case statements use expressions (compile-time constant ones), which can include the comma operator.

Yes, they can contain one, but not on that level. Initially it must be a conditional expression, so

using 1,3:

or

case 1,3:

would not be contain a valid constant expression.

- Daniel

martin.d...@gmail.com

unread,
Nov 10, 2012, 11:42:21 PM11/10/12
to std-dis...@isocpp.org, atch...@gmail.com
Just my two cents,
Up to now, there seems to have been two suggestions to make the switch statement safer:

 - Change the semantics of existing switch and silently break code.
 - Add a new syntax that would not break.

But there is a third idea that does not seem to have been considered: enforce existing rules with existing syntax. It could be require that each case containing an expression end with the keyword "break" or "continue". That would make the intention obvious and would result in a compile-time error when existing code is break.

switch(n)
{
case 1:
   foo
();
   
continue;
case 2:
   bar
();
   
break;
case 3:
case 4:
case 5:
   baz();
   
break;
}

Notice how case 3 and case 4 does not need any keyword since there is no expression directly after the case.

I am not sure if the pros to upgrade the switch can beat the cons, but if it worth the effort, I would prefer a compile-time error to a changing behavior.

Martin

Nevin Liber

unread,
Nov 11, 2012, 12:33:43 AM11/11/12
to std-dis...@isocpp.org
On 10 November 2012 22:42, <martin.d...@gmail.com> wrote:
But there is a third idea that does not seem to have been considered: enforce existing rules with existing syntax. It could be require that each case containing an expression end with the keyword "break" or "continue".

The big downside is that it is no longer compatible with C, C++03 or C++11.

Tony V E

unread,
Nov 11, 2012, 3:03:59 AM11/11/12
to std-dis...@isocpp.org
I'd prefer something that modifies the 'switch' instead of the 'case'.  How about 'explicit'?

ie:

explicit switch (v)
{
}

or

switch explicit (v)
{
}

But then you probably need a fallthrough keyword.  !break maybe? (only half joking)

Also, if you used 'using' that would imply that you could mix and match 'case' and 'using'. I don't think most people wanting safe switch would want that mix.

Tony


From: "atch...@gmail.com" <atch...@gmail.com>
To: "std-dis...@isocpp.org" <std-dis...@isocpp.org>
Sent: 10 November, 2012 12:55 PM
Subject: Re: [std-discussion] Make switch statement safe by default
--
 
 
 

atch...@gmail.com

unread,
Nov 11, 2012, 7:04:03 AM11/11/12
to std-dis...@isocpp.org, atch...@gmail.com, martin.d...@gmail.com
But there is a third idea that does not seem to have been considered: enforce existing rules with existing syntax. It could be require that each case containing an expression end with the keyword "break" or "continue". That would make the intention obvious and would result in a compile-time error when existing code is break.

I believe that this is the most elegant option and I'd be very happy to have it.

Alisdair Meredith

unread,
Nov 11, 2012, 8:37:23 AM11/11/12
to std-dis...@isocpp.org

On 11Nov, 2012, at 3:03 AM, Tony V E <tvan...@gmail.com> wrote:

> I'd prefer something that modifies the 'switch' instead of the 'case'. How about 'explicit'?
>
> ie:
>
> explicit switch (v)
> {
> }
>
> or
>
> switch explicit (v)
> {
> }
>
> But then you probably need a fallthrough keyword. !break maybe? (only half joking)
>
> Also, if you used 'using' that would imply that you could mix and match 'case' and 'using'. I don't think most people wanting safe switch would want that mix.
>
> Tony

"do not break;"

;~)

Although I would prefer 'continue' myself.

AlisdairM

Ville Voutilainen

unread,
Nov 11, 2012, 8:46:44 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 15:37, Alisdair Meredith <alis...@me.com> wrote:
>> But then you probably need a fallthrough keyword. !break maybe? (only half joking)
> "do not break;"
> ;~)

That of course is do !break;

> Although I would prefer 'continue' myself.

I have good news! We have a fall-through keyword:

switch (val) {
case 1: goto second;
second: case 2: /* whatever */
};

The fall-through keyword has an argument that you may want to keep
unique across your
case labels. ;)

atch...@gmail.com

unread,
Nov 11, 2012, 8:58:53 AM11/11/12
to std-dis...@isocpp.org
I have good news! We have a fall-through keyword:


switch (val) {

case 1: goto second;

second: case 2: /* whatever */

};

This do not solve the problem my OP was intended to solve - get the burden of remembering to put break at the end of each case, from programmer's shoulders. If anything your solution is:
a) ugly
b) requires more typing than necessary
c) there is already existing solution which solves this problem without the unnecessary over-verbose typing:
switch(val)
{
case 1:
case 2:
}

Why on earth would I want to use the ugly goto syntax if I have terse and clean syntax by default? 

Ville Voutilainen

unread,
Nov 11, 2012, 9:07:22 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 15:58, <atch...@gmail.com> wrote:
>>> I have good news! We have a fall-through keyword:
> switch (val) {
> case 1: goto second;
> second: case 2: /* whatever */
> };
> This do not solve the problem my OP was intended to solve - get the burden
> of remembering to put break at the end of each case, from programmer's
> shoulders. If anything your solution is:

Oh, pardon me, that should've been an explicit switch like Tony
proposed. Then it
does a break automatically, unless you fall through, or jump, which is
what a goto does.
Given that the fall-through is claimed to be rare, it doesn't have to
be beautiful.

Anton Golov

unread,
Nov 11, 2012, 9:09:37 AM11/11/12
to std-dis...@isocpp.org
> case 1: goto second;
> second: case 2: /* whatever */

Did you mean for the case and label to be the other way around?



--




Ville Voutilainen

unread,
Nov 11, 2012, 9:12:49 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 16:09, Anton Golov <jes...@gmail.com> wrote:
>> case 1: goto second;
>> second: case 2: /* whatever */
> Did you mean for the case and label to be the other way around?

No. I meant it to be

explicit switch {
case 1: goto second; /* if you don't jump, the case will auto-break in
an explicit switch */
second: case 2: /* via the goto, we end up falling through to case 2 */
};

I'm not quite convinced that's a good solution myself, which is why it
was proposed tongue firmly
in cheek. I'd recommend people who want to reinvent control structures
to explore lambdas to
do it. I have personally written a no-fall-through "super-case" that
can switch any type that has
an operator==, and I did that with lambdas and variadic templates, as
a library solution using
c++11 facilities.

atch...@gmail.com

unread,
Nov 11, 2012, 9:13:59 AM11/11/12
to std-dis...@isocpp.org
Given that the fall-through is claimed to be rare

I claimed (based on initial response and my own experience) that is rare, and I was told that is not so rare at all and that's why my solution is bad. I proposed something which makes C++ code safe and clean, you propose adding extra ugly (unnecessary) wordy "workaround". I simply cannot understand the rationale behind such thinking.

I believe that what martin proposed is the best solution so far. And is elegant. I like elegant. I do elegant. I want elegant. C++ can be elegant. You say just because it's rare enough it can be ugly. What a warped attitude. And who decides then what rare enough? What's rare enough? Unbelievable.  

Ville Voutilainen

unread,
Nov 11, 2012, 9:18:59 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 16:13, <atch...@gmail.com> wrote:
>> Given that the fall-through is claimed to be rare
> I claimed (based on initial response and my own experience) that is rare,
> and I was told that is not so rare at all and that's why my solution is bad.
> I proposed something which makes C++ code safe and clean, you propose adding
> extra ugly (unnecessary) wordy "workaround". I simply cannot understand the

What I have actually proposed is using lambdas to reinvent control
structures, and
I have proposed that multiple times. That doesn't even require language changes,
so once you come up with a lambda control structure that is actually
in wide use, then
it could be more reasonably considered as a language change. And if such control
structures don't end up being widely used, why should we add them to
the language?
Switch is a known beast. Some people just avoid it due to problems
with fall-through.
Creating an enhanced switch just might not be a very good solution.

atch...@gmail.com

unread,
Nov 11, 2012, 9:25:40 AM11/11/12
to std-dis...@isocpp.org
I'd recommend people who want to reinvent control structures
to explore lambdas to
do it. I have personally written a no-fall-through "super-case" that
can switch any type that has
an operator==, and I did that with lambdas and variadic templates, as
a library solution using
c++11 facilities.

So in order to have something as basic as switch to work in safe mode I have to turn expert first and then write it myself.  Is that the way to go for C++? Only experts can use it efficiently and if you're not, then 'deal with it' or find other language? Is that what's the committee is trying to lead C++ into?

Ville Voutilainen

unread,
Nov 11, 2012, 9:30:43 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 16:25, <atch...@gmail.com> wrote:
> So in order to have something as basic as switch to work in safe mode I have
> to turn expert first and then write it myself. Is that the way to go for
> C++? Only experts can use it efficiently and if you're not, then 'deal with
> it' or find other language? Is that what's the committee is trying to lead
> C++ into?

You can always choose to use if-else instead of switch, if the fall-through of
switch bothers you so much. Adding a new kind of switch is, once
again, not without
costs. Changing the existing switch is unreasonable, so it would be good to look
for alternative solutions before adding yet another language feature.

atch...@gmail.com

unread,
Nov 11, 2012, 9:33:21 AM11/11/12
to std-dis...@isocpp.org
Changing the existing switch is unreasonable

Says who?

And what's unreasonable in making language constructs safer to use?

Ville Voutilainen

unread,
Nov 11, 2012, 9:35:28 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 16:33, <atch...@gmail.com> wrote:
>> Changing the existing switch is unreasonable
> Says who?

Many people have pointed out that they don't accept the amount of code breakage
it causes.

> And what's unreasonable in making language constructs safer to use?

It may become unreasonable if the costs overcome the benefits.

atch...@gmail.com

unread,
Nov 11, 2012, 9:44:24 AM11/11/12
to std-dis...@isocpp.org
It may become unreasonable
 
 First you stated it now you are supposing it. That's a big difference. And after all - are we suppose to work on improving C++ or on cutting costs? Because as far as your arguments go costs are the most important aspects. Not language uniformity, safety, cleanliness, but costs. And then I work for people like you who instead of spending additional 30% of original cost in the inception of a project, refuse to do it, cut all possible corners, and make the project finished a week! before dead line, only to discover bug after bug, after bug, and the costs of removing them are always greater than the initial cost + 30% which would ensure high quality product from the start + high reputation. But hey, they finished project week! before dead line and they spending was lesser than expected. Aren't they great managers. 

I'm not saying that thriftiness is bad. I also don't like to spend money for everything I see. But sometimes there are more important things like initial cost.

It may become unreasonable if the costs overcome the benefits.

So the benefits of writing safer code by everyone are obviously of no interest for committee. Got it.

Ville Voutilainen

unread,
Nov 11, 2012, 9:48:12 AM11/11/12
to std-dis...@isocpp.org
On 11 November 2012 16:44, <atch...@gmail.com> wrote:
>> It may become unreasonable if the costs overcome the benefits.
> So the benefits of writing safer code by everyone are obviously of no
> interest for committee. Got it.

Your conclusions from what I say are pure fantasy, and a deliberate
misrepresentation
of what I said. You seem to be completely impervious to any feedback,
too. So, I shall
leave you to it.

atch...@gmail.com

unread,
Nov 11, 2012, 10:04:50 AM11/11/12
to std-dis...@isocpp.org
It is you who cannot specify what the real/tangible costs are. The only thing you do is:
a) Stating/supposing that there are enormous costs, so nothing seem to be worth doing, not even for the sake of having safe concepts in a language.
b) providing ugly workarounds and being content.

Got it. If I'm misinterpreting anything is only because you cannot express yourself in clear and unambiguous manner.

michael...@gmail.com

unread,
Nov 13, 2012, 12:31:18 AM11/13/12
to std-dis...@isocpp.org, atch...@gmail.com
Watching from the sidelines is great, but I don't think any more progress will be made in the forum on this topic.  That is my opinion (which doesn't count much).

I will however say that the costs for getting such a change are in fact real, and the discussions, such as the one taking place here is only one small example.

As a pretty heavy user of C++ and a former University-level instructor that is not on the committee, I would not support changing the behavior of the current syntax and have bad feelings towards introducing a different syntax that would need to be taught to students.  I've read the argument for and against the various incarnations, and that is my well-formed opinion.

ri...@longbowgames.com

unread,
Nov 17, 2012, 9:25:52 PM11/17/12
to std-dis...@isocpp.org, atch...@gmail.com, michael...@gmail.com
There's some pretty extreme suggestions in this thread. It occurs to me that there's a much simpler solution: simply introduce a keyword that allows the programmer to declare their intent to fallthrough, but don't require the compiler to enforce it. For example, if you wrote this:

switch(someVar)
{
case 'a':
case 'b':
  cout << "Foo";
  fallthrough;
case 'c':
  cout << "Bar";
case 'd':
  cout << "Baz";
};

...then the compiler might issue a warning like this:

Warning on line 9: Non-empty case 'c' followed by case 'd' without break or fallthrough keyword.

...but the code would still compile. Of course, you could tell your compiler to treat those warnings as errors, but it wouldn't break any existing code unless you explicitly ask it to. I think it would be adopted as proper idiomatic C++ fairly quickly, and maybe one day it could be enforced by the standard, but not until its impact is minimized.

Chris Jefferson

unread,
Nov 18, 2012, 2:42:58 AM11/18/12
to std-dis...@isocpp.org
On 18/11/12 02:25, ri...@longbowgames.com wrote:
> There's some pretty extreme suggestions in this thread. It occurs to
> me that there's a much simpler solution: simply introduce a keyword
> that allows the programmer to declare their intent to fallthrough, but
> don't require the compiler to enforce it. For example, if you wrote this:
...
As I already said (in this big thread), this already exists (in clang).
Attributes are ideal for this purpose, as they are supposed to not
change the behaviour of code.

int switcher(char someVar)
{
int ret = 0;
switch(someVar)
{
case 'a':
case 'b':
ret = 1;
[[clang::fallthrough]];
case 'c':
ret = 2;
case 'd':
ret = 3;
};
return 0;
}

Gives (with appropriate warning flag, not enabled by default yet)

switch.cc:12:5: warning: unannotated fall-through between switch labels
[-Wimplicit-fallthrough]
case 'd':
^
switch.cc:12:5: note: insert '[[clang::fallthrough]];' to silence this
warning
case 'd':
^
[[clang::fallthrough]];
switch.cc:12:5: note: insert 'break;' to avoid fall-through
case 'd':
^
break;

masse....@gmail.com

unread,
Nov 20, 2012, 7:55:12 AM11/20/12
to std-dis...@isocpp.org
I'd say that attributes are not a real solution because :
- It can't affect the behaviour of the code, so code that does compile today will still compile tomorrow
- I find it quite verbose

For my part, i'd rather see a move in 2 steps:
- First (C++14?), introducing a new keyword (say fall) in order to say that at the end of the case block, we must "fall" into the next one.
Introducing a new keyword is required (I think) because I don't see any suitable in the existing ones.
I also tough about the continue keyword, but it will change the behaviour of existing code if we are inside a loop, which make this unacceptable.
During that first period, having  a case without any break/fall is still supported, but should be considered as a deprecated feature.

- Second (C++17?), the (obsolete at this time) support of cases without break/fall should be dropped. 
People will have already at least 3 years to upgrade their code, so such a change could be accepted here.

Concretely, this code :
int a = doSomething();
switch(a)
{
case 1:
case 2:
   doSomethingElse(); 
case 3:
    doSomethingElse2(); 
    break;
default:
     doSomethingElse2(); 
}

will be considered as :
 - valid in c++11 
 - obsolete in c++14 (compilers will probably produce a warning here)
 - invalid in  c++17
To make this code ok in c++17, you will have to add the fall   keyword in the 1st block, but also a break in the default block:
int a = doSomething();
switch(a)
{
case 1:
case 2:
   doSomethingElse(); 
   fall;
case 3:
    doSomethingElse2(); 
    break;
default:
     doSomethingElse2();     
     break; //note that putting a fall here won't change anything since it's the last block :-)
}
Note : About adding a keyword just after the switch to show the default behaviour :
I don't really see a need for this, and I think that it could makes code harder to read if you have an important block of code inside one or severals cases block for example.
Anyway, if people wants to consider this, they could, but the default behaviour SHOULD BE SET TO FALL, NOT TO BREAK, because otherwise it will break existing code, which is unacceptable.

Patrick Michael Niedzielski

unread,
Nov 20, 2012, 10:21:24 AM11/20/12
to std-dis...@isocpp.org
Hi masse.nicolas,

On mar, 2012-11-20 at 04:55 -0800, masse....@gmail.com wrote:
> I'd say that attributes are not a real solution because :
>
> - It can't affect the behaviour of the code, so code that does compile
> today will still compile tomorrow

I think this was the point of suggesting attributes as a solution. We
don't want a solution that breaks code that already compiles. I don't
see a point in breaking code that compiles already anyway. It doesn't
seem like the standards' job to break code to point out *possible* bugs
in it. In mature code bases, there is a very high chance that most
fall-throughs are deliberate, so code that works today exactly as
expected would be broken tomorrow because it used the correct (until
now) language features. That is not acceptable.

> - I find it quite verbose

That is a fair enough objection, we do need to remember that this is a
subjective objection. We all agree that a solution that is too verbose
is bad, but what constitutes "too verbose" probably changes depending on
who you ask. :)

If we look at our requirements both for this feature and for a change to
the standard (I've taken the original problem as one of the
requirements, added the requirement that I proposed above, and then put
both of the two requirements that you added in response to attributes.
More requirements can be added, removed, etc):

1. Make explicit fall-throughs in case statements to point out
unintentional ones.
2. Breaks minimal code (people don't like it when their working
code breaks) => something the standards committee will be
thinking about
3. Code that compiles today and doesn't use this feature may
contain bugs, so it should not compile without using this
feature.
4. Isn't verbose.

2 and 3 are definitely mutually exclusive (save for some cases where the
user has declared that such code should not compile, with something like
-Wall -Werror, outside the scope of the standard), so we need to find
which is more important. I personally take 2 to be more important.

Attributes are nice solution if we take requirement 2 to be more
important than 3, because they 1) allow explicit marking of code
semantics, so an accidental fall-through can be warned about, 2) don't
break existing code that most likely does work, 3) don't necessitate a
change to the core language, as they can be implemented by each vendor.
The final point is a possibility, but they could also be implemented in
the standard.

A vendor implementation could produce a warning when it doesn't
encounter this attribute, and a vendor implementation could make that
warning an error. This gives exactly the behavior you want, but is in
control of the user. If an old codebase which was thoroughly tested
uses the proper C++11 syntax and contains no bugs, the warning could be
turned off, and code could continue to compile. The user could then opt
out of this feature for large codebases that they know work, rather than
modify them.

A new keyword, especially one as general as "fall", seems almost to be a
non-starter. I've used "fall" as an identifier name, and I'm sure it is
not used infrequently by others, as well. Not infrequently enough that
it could be used as a keyword. I understand that "fall" as a keyword
was an example, but for a new keyword, substantial effort needs to be
taken to make sure it won't break existing code that follows the
standard. It's not a good idea to break programs that may not even use
a switch statement by introducing a new keyword. "nobreak" *could* be a
better solution, but something like "[[fall]]" is an even better
solution. It would break no existing code and is only four characters
more verbose than "fall". The exact attribute could be changed, taking
into account verbosity.

For completeness, I should mention something like the "override"
contextual keyword in C++11. I don't think it could be used here,
although I haven't much thought about it, because it would introduce
either ambiguities or restrictions that aren't present in function
signature contextual keywords. Take the signature:

virtual void foo(char* arg) override;

In C++03, no token could appear here, excepting a "=" and a "0". No
ambiguity is added by adding contextual keywords here. Now consider the
switch statement:

int a = /* ... */;
int fall = 0;
switch (a) {
case 0:
case 1:
do_foo();
fall; // #1
fall = 1; // #2
case 2:
more_foo();
break;
}

With line #1, I want to point out that the contextual keyword introduces
ambiguity (albeit, ambiguity between a keyword and a useless statement).
This was not the case with the function signature contextual keyword
above. This could be ignored, under the premise that no one would write
that statement, but it does introduce an asymmetry that the other
solutions don't have, wherein this statement is allowed in some places
but not in all places. With line #2, I want to show that the contextual
keyword would have to have the form of the statement in #1, or it would
break conforming code and actually introduce bugs if it does so
silently.

These are just ideas to think about, not a wholesale rejection of your
proposal.

Cheers,
Patrick Niedzielski
signature.asc

ri...@longbowgames.com

unread,
Nov 21, 2012, 12:12:35 AM11/21/12
to std-dis...@isocpp.org
I'm perfectly happy with using an attribute, and I'm pleased to learn that attributes are flexible enough to be used in a context like this. Attributes have the benefit of not clashing with identifiers and not introducing a new keyword, which have historically made compiler writers rather nervous.

The downside is that if this attribute becomes idiomatic enough that everybody turns this error on by default, then it no longer qualifies as something that doesn't affect program flow, and it would be surprising to people learning that language that they have to use this strange bracketed keyword.

But that's pretty far in the future, and it's not an unsolvable problem. If we ever find ourselves in that situation, it would be worth considering adding a keyword which aliases the legacy attribute. The language would end up with an odd wart of history, but that's far from the end of the world.

ri...@longbowgames.com

unread,
Nov 21, 2012, 12:46:39 AM11/21/12
to std-dis...@isocpp.org, ri...@longbowgames.com
Thinking it through a bit more, if we use an attribute, that attribute should 'belong' to the case statement. It wouldn't make sense if you were permitted to do this:

switch(i)
{
case 1:
  if(x == y)
    [[fallthrough]];
  ++x;
  break;
case 2:
  // Do something
}


I'm sure people would be quick to find uses and abuses for a feature like that, but it affects program flow, which makes it unsuitable for attributes. Logically, it should be parsed more like this:

switch(i)
{
case 1:
  // Do something
[[fallthrough]] case 2:
  // Keep on doin'.
}

Richard Smith

unread,
Nov 21, 2012, 9:16:49 PM11/21/12
to std-dis...@isocpp.org, ri...@longbowgames.com
On Tue, Nov 20, 2012 at 9:46 PM, <ri...@longbowgames.com> wrote:
> Thinking it through a bit more, if we use an attribute, that attribute
> should 'belong' to the case statement. It wouldn't make sense if you were
> permitted to do this:

We discussed these cases at length when we were designing the
[[clang::fallthrough]] attribute.

> switch(i)
> {
> case 1:
> if(x == y)
> [[fallthrough]];
> ++x;

We give an error here, because control flow through the
[[fallthrough]]; attribute isn't immediately followed by a
fallthrough.

> break;
> case 2:
> // Do something

We allow this:

if (x == y)
break;
else if (x == z)
[[fallthrough]];
else
return 0;
case 3:

I'm not sure that allowing this is the best design, however: it's easy
to miss the existence of the fallthrough attribute when reordering
cases.

> }
>
> I'm sure people would be quick to find uses and abuses for a feature like
> that, but it affects program flow, which makes it unsuitable for attributes.
> Logically, it should be parsed more like this:
>
> switch(i)
> {
> case 1:
> // Do something
> [[fallthrough]] case 2:
> // Keep on doin'.
> }

Attaching it to a case (or goto) label is tempting, but it's visually
more appealing to put the fallthrough on the previous line, and we
found that things work out better if it's followed by a semicolon
(text editors are happier, and it looks nicer).

As another data point, MSVC has a __fallthrough keyword, which appears
to be modeled as a statement. It would be sensible to draw from their
experiences too.


One other thing to consider is that fallthrough detection depends on
the implementation's ability to determine whether a particular
statement is reachable, and different implementations make different
tradeoffs when performing such checks (for instance, g++ tends to
perform this sort of check after performing some optimizations, and
the forms of expressions which an implementation is prepared to
constant-fold also make a difference). As an example, consider this:

enum E { a, b, c };
int f(int n, E e) {
switch (n) {
case 0:
switch (e) {
case a: return 1;
case b: return 2;
case c: return 3;
}
default:
return 4;
}
}

Does this code have unannotated fallthrough? Clang conservatively
assumes that the value of 'e' will be 'a', 'b', or 'c' when checking
reachability, so suppresses its fallthrough warning on this case, even
though in principle the value of 'e' could be (E)3.

j12x

unread,
Nov 23, 2012, 5:38:26 PM11/23/12
to std-dis...@isocpp.org

FWIW "continue" will break (no pun intended) some valid code. You will have to come up with another keyword:

for (int i = 0; i < 10; ++i) {
switch (i) {
case 1:
foo();
continue; // continue for loop
case 2:
bar();
break;
}
}

ri...@longbowgames.com

unread,
Nov 24, 2012, 8:11:21 AM11/24/12
to std-dis...@isocpp.org, jacques...@gmail.com
C# has an interesting solution: overload the goto keyword:

switch(someVar)
{
case 'a':
case 'b':
  cout << "Foo";
  goto case 'c';
case 'c':
  cout << "Bar";
  goto default;
default:
  cout << "Baz";
};

atch...@gmail.com

unread,
Nov 25, 2012, 8:55:33 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com
But this is simply to verbose and you can already do it in C++ with goto keyword. I simply don't see a point in it. The whole point of my proposal was to:
a) make writing safe C++ code easier, and special cases only require extra wording, not as it is now that the default/most common behavior needs to be specified explicitly (pun intended)
b) make C++ safe by default.

Attributes shouldn't be used. The support for this structure should come from the core of the language. Also, attributes don't solve this problem, but only add one more: one still have to remember of them, while what I'm proposing is, that the burden of remembering is lifted from programmers shoulders. I personally like this best (this was suggested by Martin):

But there is a third idea that does not seem to have been considered: enforce existing rules with existing syntax. It could be require that each case containing an expression end with the keyword "break" or "continue". That would make the intention obvious and would result in a compile-time error when existing code is break.

switch(n)
{
case 1:
foo();
continue;
case 2:
bar();
break;
case 3:
case 4:
case 5:
baz();
break;
}

Notice how case 3 and case 4 does not need any keyword since there is no expression directly after the case.

The above is, I believe most elegant and simple. 

ri...@longbowgames.com

unread,
Nov 25, 2012, 9:05:18 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
We've been over this. I agree that using continue is an elegant solution, but it's a non-starter because it breaks the following code:

for(int i = 0; i < 10; ++i)
{
  switch(c)
  {
    case 'a':
      continue;
    case 'b':
      ++i;
  }
}


That code works in present-day C++, but it doesn't do what you want.


On Sunday, November 25, 2012 8:55:33 AM UTC-5, atch...@gmail.com wrote:
But this is simply to verbose and you can already do it in C++ with goto keyword.

You are mistaken. C++ does not currently support 'goto case'.

A large part of making a standard is being pragmatic.  'goto case' would allow compiler vendors to warn on implicit fallthrough, wouldn't require any new keywords, wouldn't break any existing code, and has precedence.

atch...@gmail.com

unread,
Nov 25, 2012, 9:26:53 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
We've been over this. I agree that using continue is an elegant solution, but it's a non-starter because it breaks the following code:
It does not. The code behaves exactly as specified: after continue control goes back to loop, and that is exactly what Martin suggested:
"It could be require that each case containing an expression end with the keyword "break" or "continue" " - I read it as it states, not that there are two keywords with the same meaning.

atch...@gmail.com

unread,
Nov 25, 2012, 9:34:27 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
You are mistaken. C++ does not currently support 'goto case'.

I am not mistaken. I said that goto is supported and what you've presented in your example is already achievable in current C++ (with slight modifications). But the whole point is that the user shouldn't every time remember to put this goto/break. This should be implicit, because that's the nature of switch. You have different cases for different "cases" and you (mostly) want them to be executed separately, not one after another. The point I'm trying to make over and over again, is that C++ should go into direction of writing C++ code with most common meaning:
a) easy out of box. - no repetition of obvious and most common meaning/usage - here no repetition of break
b) safe out of box. - no need to remember each time you write a case that the break must be at the end. The switch statement has it at its core to have different cases for different values and this should be reflected in the way you write your code. You shouldn't repeat constantly that you want break after this or the other 'case'. It is implicit. It is switch. That's the whole purpose of it. And that's how you should code in modern, safe out of box C++.

Adding another keyword, attribute simply makes things even worse. I don't see how adding another keyword that needs to be remembered and typed easies the work of a programmer. 

On Sunday, 25 November 2012 14:05:18 UTC, ri...@longbowgames.com wrote:

ri...@longbowgames.com

unread,
Nov 25, 2012, 9:48:09 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
Are you here to try to help programmers, or just to complain?

Sure, if we had a time machine and could go back to 1972 to convince Dennis Richie to use implicit break, it would make C and C++ more elegant languages. But we don't and we can't.

Implicit break is never going to happen. Period. It would break existing, valid code, and the standards committee would never accept it.

What we can do is give programmers the tools they need to avoid accidentally invoking implicit fallthrough.

atch...@gmail.com

unread,
Nov 25, 2012, 9:57:07 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
Are you here to try to help programmers, or just to complain?

Where did I complain? 

Implicit break is never going to happen. Period. It would break existing, valid code, and the standards committee would never accept it.

C++11 broke existing code with committee's knowledge. As Dave Abrahams said, C++14 and later will most likely do it again.

So to answer to your question, no I'm not here to complain, but I'm also not here to make C++ harder and harder to use. I want C++ to be easy and safe to use out of box. It is possible. It is doable. The old thinking must change.

atch...@gmail.com

unread,
Nov 25, 2012, 9:58:01 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
What we can do is give programmers the tools they need to avoid accidentally invoking implicit fallthrough.

We already have it: break keyword does exactly this. 

On Sunday, 25 November 2012 14:48:09 UTC, ri...@longbowgames.com wrote:

atch...@gmail.com

unread,
Nov 25, 2012, 9:58:46 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
Implicit break is never going to happen

It's not about implicit break. It's about cleaner, more natural rules. 

Ville Voutilainen

unread,
Nov 25, 2012, 10:16:45 AM11/25/12
to std-dis...@isocpp.org
On 25 November 2012 16:58, <atch...@gmail.com> wrote:
>> Implicit break is never going to happen
> It's not about implicit break. It's about cleaner, more natural rules.

Well, propose something that will not break existing switch-cases then.
Changing the existing rules to achieve something cleaner and more natural
has the downside of breaking (potentially lots of) existing code, so that's
unlikely to happen.

ri...@longbowgames.com

unread,
Nov 25, 2012, 10:24:51 AM11/25/12
to std-dis...@isocpp.org, jacques...@gmail.com, ri...@longbowgames.com, atch...@gmail.com
On Sunday, November 25, 2012 9:57:08 AM UTC-5, atch...@gmail.com wrote:
C++11 broke existing code with committee's knowledge. As Dave Abrahams said, C++14 and later will most likely do it again.

It's important that you understand how C++11 broke existing code. It broke code that used identifiers like 'constexpr' and 'decltype'. It broke code that both used using namespace std and used an identifier from the new library extensions, like 'unordered_map'.

And with each of those decisions, the committee did it with great hesitation. They conducted research to discover how much existing code would be affected. This is the reason we call it 'unordered_map' instead of the simpler 'hash_map'.

C++11 is incompatible with C++98 in the same way that C++ is incompatible with C because C++ defined 'class' as a keyword. It's very rare for these incompatibilities to pop up.

If even 1% of users are affected by a change, the committee is going to be concerned.

Arthur Tchaikovsky

unread,
Nov 25, 2012, 11:06:07 AM11/25/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
This is the reason we call it 'unordered_map' instead of the simpler 'hash_map'.

To be honest, I simply see it as a mistake. ISO Standard should have
precedence over anything else and if code needs to be broken so will
it be. But next standard and code produced is cleaner/better/safer
etc. In order to build highways you need to knock down someones houses
sometimes. But there are significant trade offs. As the things go now
I simply don't see C++ to become easier to learn/use.

On 11/25/12, ri...@longbowgames.com <ri...@longbowgames.com> wrote:
> On Sunday, November 25, 2012 9:57:08 AM UTC-5, atch...@gmail.com wrote:
>>
>> C++11 broke existing code with committee's knowledge. As Dave Abrahams
>>> said, C++14 and later will most likely do it again.
>>
>>
> It's important that you understand how C++11 broke existing code. It broke
> code that used identifiers like 'constexpr' and 'decltype'. It broke code
> that *both* used using namespace std and used an identifier from the new
> library extensions, like 'unordered_map'.
>
> And with each of those decisions, the committee did it with great
> hesitation. They conducted research to discover how much existing code
> would be affected. This is the reason we call it 'unordered_map' instead of
>
> the simpler 'hash_map'.
>
> C++11 is incompatible with C++98 in the same way that C++ is incompatible
> with C because C++ defined 'class' as a keyword. It's *very* rare for these

ri...@longbowgames.com

unread,
Nov 25, 2012, 11:21:33 AM11/25/12
to std-dis...@isocpp.org, ri...@longbowgames.com, jacques...@gmail.com, atch...@gmail.com
We all wish C++ had a simpler, more consistent syntax. Even Herb Sutter, the convener of the C++ committee, said he wishes it had a complete left-to-right syntax. But C++ has one of the largest code bases in the world, and one of the reasons it got so popular in the first place is because it's compatible with C. There's no getting around that reality.

Trust me, I've thought a lot about how we could pave the way to improving the syntax. Maybe after modules, we could standardize the format of the AST, and then invent a new syntax that conforms to the same AST. But if that has any chance of happening, it's not until at least some time in the 2020's.

In the meantime, there's at least a decade of code that can be improved by giving compilers a way to detect when a programmer has accidentally invoked implicit fallthrough.

Arthur Tchaikovsky

unread,
Nov 25, 2012, 11:27:34 AM11/25/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
I do see your point. Nonetheless, even the longest journey starts with
a single step.
I repeat, the old washion way of thinking must change - don't break my code?
In the first place, learn how to write safe, maintainable and correct
code. Then it will not get broken. Otherwise you're on your own.

Those words weren't of course directed at you personally.
> We all wish C++ had a simpler, more consistent syntax. Even Herb Sutter,
> the convener of the C++ committee, said he wishes it had a complete
> left-to-right syntax. But C++ has one of the largest code bases in the
> world, and one of the reasons it got so popular in the first place is
> because it's compatible with C. There's no getting around that reality.
>
> Trust me, I've thought a lot about how we could pave the way to improving
> the syntax. Maybe after modules, we could standardize the format of the
> AST, and then invent a new syntax that conforms to the same AST. But if
> that has any chance of happening, it's not until *at least* some time in

ri...@longbowgames.com

unread,
Nov 25, 2012, 11:49:51 AM11/25/12
to std-dis...@isocpp.org, ri...@longbowgames.com, jacques...@gmail.com, atch...@gmail.com
You quoted Dave Abrahams earlier. I have another quote by him:

I continue to object to declarations that code “deserves to be broken” because it doesn’t conform to a particular philosophy of how code should be written. And even if I bought into your idea ... it is even more wrong of the language to kill “wrong” programs in the field without also giving users strong tools for avoiding wrong programs in the first place.

Your suggestion is particularly dangerous because not only does it break code, but it does so silently. Even if I never used fallthrough in my life, I could be using a library that uses fallthrough, and my code suddenly gets buggy, by no fault of my own, just because I upgraded my compiler.

Now, if you had suggested that switch[break] does what you want, but the existing logic of an unadorned switch remains unchanged, then that's a workable solution. I have a few qualms with it, but it doesn't break existing code, so at least it's in the realm of plausibility.

Arthur Tchaikovsky

unread,
Nov 25, 2012, 11:56:40 AM11/25/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
"Your suggestion is particularly dangerous because not only does it
break code, but it does so silently"

I simply don't understand how? If anything you get compiler errors.
What's wrong with it?
> You quoted Dave Abrahams earlier. I have another quote by him:
>
> I continue to object to declarations that code “deserves to be broken”
>> because it doesn’t conform to a particular philosophy of how code should
>> be
>> written. And even if I bought into your idea ... it is even more wrong of
>>
>> the language to kill “wrong” programs in the field without also giving
>> users strong tools for avoiding wrong programs in the first place.
>>
>
> Your suggestion is particularly dangerous because not only does it break
> code, but it does so *silently*. Even if I never used fallthrough in my

ri...@longbowgames.com

unread,
Nov 25, 2012, 12:20:43 PM11/25/12
to std-dis...@isocpp.org, ri...@longbowgames.com, jacques...@gmail.com, atch...@gmail.com
On Sunday, November 25, 2012 11:56:42 AM UTC-5, Arthur Tchaikovsky wrote:
I simply don't understand how? If anything you get compiler errors.
What's wrong with it?

No, you wouldn't get a compiler error.

Let's say I write this:

string s = "abracadabra";
int countA = 0;
int countAll = 0;

for(auto c : s)
{
  switch(c)
  {
    case 'a':
      countA++;
    default:
      countAll++;
  }
}


Then with an existing compiler, countAll == 11, but with your suggestion, countAll == 6. In neither case does it cause a compiler error.

wolfei...@gmail.com

unread,
Nov 25, 2012, 1:06:26 PM11/25/12
to std-dis...@isocpp.org
There's no reason to introduce a new fall or fallthrough keyword. Just use "continue". That would be fine for me.

But ultimately, I'd really rather see a switch v2 that can cope with other types and all sorts of things rather than a minor modification to the existing switch that still breaks every iota of code using it.

ri...@longbowgames.com

unread,
Nov 25, 2012, 1:09:03 PM11/25/12
to std-dis...@isocpp.org, wolfei...@gmail.com
We've explained why continue breaks existing code four or five times in this thread already.

wolfei...@gmail.com

unread,
Nov 25, 2012, 1:09:38 PM11/25/12
to std-dis...@isocpp.org, wolfei...@gmail.com, ri...@longbowgames.com
Whoops, my bad. It's very long and I missed a few messages.

Christof Meerwald

unread,
Nov 25, 2012, 1:32:06 PM11/25/12
to std-dis...@isocpp.org
On Sun, Nov 25, 2012 at 05:16:45PM +0200, Ville Voutilainen wrote:
> On 25 November 2012 16:58, <atch...@gmail.com> wrote:
> >> Implicit break is never going to happen
> > It's not about implicit break. It's about cleaner, more natural rules.
> Well, propose something that will not break existing switch-cases then.

Here is a random thought - new-style case labels that don't allow
implicit fallthrough, e.g.

switch (i)
{
case { 1 }:
foo();

case { 2, 4, 8, 16 }:
bar();
}


Christof

--

http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

Ville Voutilainen

unread,
Nov 25, 2012, 1:40:05 PM11/25/12
to std-dis...@isocpp.org
On 25 November 2012 20:32, Christof Meerwald <cme...@cmeerw.org> wrote:
> Here is a random thought - new-style case labels that don't allow
> implicit fallthrough, e.g.
> switch (i)
> {
> case { 1 }:
> foo();
> case { 2, 4, 8, 16 }:
> bar();
> }

Another one:

switch (i)
{
case break 1:
foo();
case break 2:
bar();
}

I do like your idea to allow multiple values in a single case.

ri...@longbowgames.com

unread,
Nov 25, 2012, 1:55:36 PM11/25/12
to std-dis...@isocpp.org, cme...@cmeerw.org
On Sunday, November 25, 2012 1:32:08 PM UTC-5, Christof Meerwald wrote:
Here is a random thought - new-style case labels that don't allow
implicit fallthrough, e.g.

  switch (i)
  {
    case { 1 }:
     foo();

    case { 2, 4, 8, 16 }:
     bar();
  }

That's an interesting idea. It doesn't solve the default case, but most people already put that at the end anyway. Some people might take issue with the fact that it looks like an initialization, and I'm almost worried it's too similar to the old style that people might accidentally use the old style out of habit.

Another option would be:

switch(i)
{
  case(1)
  {
    foo();
  }
  case(2, 4, 8, 16)
  {
    bar();
  }
}


On Sunday, November 25, 2012 1:40:06 PM UTC-5, Ville Voutilainen wrote:
Another one:

switch (i)
{
  case break 1:
    foo();
  case break 2:
    bar();
}
 
You might as well do switch break(i) rather than repeating the break on every case. We're already including a break in every case currently :)

Christof Meerwald

unread,
Nov 25, 2012, 2:17:09 PM11/25/12
to std-dis...@isocpp.org
On Sun, Nov 25, 2012 at 10:55:36AM -0800, ri...@longbowgames.com wrote:
> On Sunday, November 25, 2012 1:32:08 PM UTC-5, Christof Meerwald wrote:
> > Here is a random thought - new-style case labels that don't allow
> > implicit fallthrough, e.g.
> >
> > switch (i)
> > {
> > case { 1 }:
> > foo();
> >
> > case { 2, 4, 8, 16 }:
> > bar();
> > }
> >
>
> That's an interesting idea. It doesn't solve the default case, but most

You could specify that you can neither fall into nor out of a
new-style case label (and probably want to disallow mixing old-style
and new-style case labels anyway).

> people already put that at the end anyway. Some people might take issue
> with the fact that it looks like an initialization, and I'm almost worried
> it's *too* similar to the old style that people might accidentally use the
> old style out of habit.

Yes, I guess the similarity with the old style would be my biggest
worry as well.

masse....@gmail.com

unread,
Nov 25, 2012, 4:36:34 PM11/25/12
to std-dis...@isocpp.org, cme...@cmeerw.org

I think it does not solve this :

int step;
//...
switch (step)
{
case 1: 
process_step1();
case 2:
process_step2();
case 3:
process_step3();
}

because here all three cases could be played if step==1.


I continue to object to declarations that code “deserves to be broken” because it doesn’t conform to a particular philosophy of how code should be written. And even if I bought into your idea ... it is even more wrong of the language to kill “wrong” programs in the field without also giving users strong tools for avoiding wrong programs in the first place.

I completely agree with this, which is why I speak about a move done in 2 steps.

Ville Voutilainen

unread,
Nov 25, 2012, 4:53:08 PM11/25/12
to std-dis...@isocpp.org
On 25 November 2012 23:36, <masse....@gmail.com> wrote:
> I think it does not solve this :
> int step;
> //...
> switch (step)
> {
> case 1:
> process_step1();
> case 2:
> process_step2();
> case 3:
> process_step3();
> }
> because here all three cases could be played if step==1.

I don't think it's intended to. If you want fall-through, you can use
the existing switch.

J. Daniel Garcia

unread,
Nov 25, 2012, 11:05:47 PM11/25/12
to std-dis...@isocpp.org, cme...@cmeerw.org
You might as well do switch break(i) rather than repeating the break on every case. We're already including a break in every case currently :)

I think this is a reasonable compromise, similar to enums (where enum is backwards compatible and enum clase has new semantics).

switch break (x) {
  case 1:
    process_one();
    // Implicit break here
  case 2:
    process_two();
    //implicit  break here
  deffault:
    process_other();
}

Now, as this is a new thing. No backward compatibility is needed (we still have the backward compatible good old switch). So we are free of adding case with lists ( case 1, 3, 5: ) or even with ranges (case {5,10}:, meaning from 5 to 10).

Having said that, my feeling is that the priority of this proposal is not high. I could live with it, but I could live without it too.
--
  J. Daniel

Arthur Tchaikovsky

unread,
Nov 26, 2012, 2:08:40 AM11/26/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
I would get compile error. For the simple reason that there is no
break keyword after countA++; and this is seen as illformed switch
statement. No break is required only if there are case statements one
after another, which indicates intentional fallthrough.
So that would be a compiler error.

ri...@longbowgames.com

unread,
Nov 26, 2012, 6:54:19 AM11/26/12
to std-dis...@isocpp.org, ri...@longbowgames.com, jacques...@gmail.com, atch...@gmail.com
On Monday, November 26, 2012 2:08:41 AM UTC-5, Arthur Tchaikovsky wrote:
I would get compile error. For the simple reason that there is no
break keyword after countA++; and this is seen as illformed switch
statement. No break is required only if there are case statements one
after another, which indicates intentional fallthrough.
So that would be a compiler error.

It's really difficult to have this conversation with you when you keep going back and forth on whether the user should have to repeat 'break' at the end of every case.

Arthur Tchaikovsky

unread,
Nov 26, 2012, 7:04:14 AM11/26/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
Hi Rick

I really don't understand what/why you are saying what you're saying.
I repeat the solution I like most, and which I've liked most since
I've seen it (proposed by Martin):

" But there is a third idea that does not seem to have been
considered: enforce existing rules with existing syntax. It could be
require that each case containing an expression end with the keyword
"break" or "continue". That would make the intention obvious and would
result in a compile-time error when existing code is break.


switch(n)
{
case 1:
foo();
continue;
case 2:
bar();
break;
case 3:
case 4:
case 5:
baz();
break;
} "

I really cannot understand where I keep coming back and forth?

ri...@longbowgames.com

unread,
Nov 26, 2012, 7:14:02 AM11/26/12
to std-dis...@isocpp.org, ri...@longbowgames.com, jacques...@gmail.com, atch...@gmail.com
On Monday, November 26, 2012 7:04:15 AM UTC-5, Arthur Tchaikovsky wrote:
Hi Rick

I really don't understand what/why you are saying what you're saying.
I repeat the solution I like most, and which I've liked most since
I've seen it (proposed by Martin):

21 hours ago, you said:

On Sunday, November 25, 2012 9:34:27 AM UTC-5, atch...@gmail.com wrote:
a) easy out of box. - no repetition of obvious and most common meaning/usage - here no repetition of break

Also, you're misunderstanding Martin's original message. At the time, he thought 'continue' could safely be used as a keyword for fallthrough.
 

Arthur Tchaikovsky

unread,
Nov 26, 2012, 7:42:21 AM11/26/12
to ri...@longbowgames.com, std-dis...@isocpp.org, jacques...@gmail.com
Rick
You're absolutely right. While I had my original proposal in mind I
was applying this to Martin's solution - which as you've pointed out
is contradictory.

I'm for Martin's solution, as I was from the first time I saw it.

Please accept my apologies for this misunderstanding - it was non-intentional.

Vicente J. Botet Escriba

unread,
Nov 25, 2012, 4:11:02 PM11/25/12
to std-dis...@isocpp.org
Le 25/11/12 19:32, Christof Meerwald a �crit :
> On Sun, Nov 25, 2012 at 05:16:45PM +0200, Ville Voutilainen wrote:
>> On 25 November 2012 16:58, <atch...@gmail.com> wrote:
>>>> Implicit break is never going to happen
>>> It's not about implicit break. It's about cleaner, more natural rules.
>> Well, propose something that will not break existing switch-cases then.
> Here is a random thought - new-style case labels that don't allow
> implicit fallthrough, e.g.
>
> switch (i)
> {
> case { 1 }:
> foo();
>
> case { 2, 4, 8, 16 }:
> bar();
> }
>
The syntax is simple, doesn't breaks C++11 code and seems to solve most
of the problems of the PO.

The addition that if one case is a break case all the cases must be
break cases and that the default case must be the last one would ensure
the coherence and easy to learn I think we are locking for.

Vicente



Nevin Liber

unread,
Nov 27, 2012, 2:14:03 PM11/27/12
to std-dis...@isocpp.org
On 25 November 2012 15:11, Vicente J. Botet Escriba <vicent...@wanadoo.fr> wrote:
The syntax is simple, doesn't breaks C++11 code and seems to solve most of the problems of the PO.

The addition that if one case is a break case all the cases must be break cases and that the default case must be the last one would ensure the coherence and easy to learn I think we are locking for.

But are we looking for it?  After almost three weeks, response has been lukewarm at best.  While at this point I wouldn't vote against this, adding a slightly better than C C-ism (after all, switch still doesn't work with user defined types) isn't much bang for the buck.  Is there someone volunteering to write the paper and present it at Bristol in April?
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

ri...@longbowgames.com

unread,
Nov 27, 2012, 3:51:28 PM11/27/12
to std-dis...@isocpp.org
Well, let's summarize. There's two ideas under discussion here.

The more conservative idea is to design a way to explicitly fallthrough (something like Clang's [[clang:fallthrough]] or C#'s goto case) and give compilers the flexibility to issue warnings when the user invokes implicit fallthrough.

The more radical idea is to design a new switch statement from first-principles that has implicit break.

Although I enjoy discussing radical ideas, this one has a lot going against it. The only real positive is that you don't have to repeat break; at the end of each case. On the negative side, users who come from languages with a C-inspired switch statement have to learn a new kind of switch statement, users who are new to programming have to learn two kinds of switch statements, and users could accidentally invoke the wrong kind of switch statement. That's a fairly large price to pay for making your case statements six characters shorter.

The conservative idea, on the other hand, is a very small price to pay for catching real errors, and having those warnings reported by the compiler would certainly make the language easier to teach.

Certainly if we were going to design a new kind of switch statement, it would be a wasted opportunity if it didn't support user-defined types (perhaps with a constexpr operator<), although I'm not convinced that couldn't be supported with the existing syntax.
Reply all
Reply to author
Forward
0 new messages