Topic: PROPOSAL: improved switch


Author: "Douglas A. Gwyn" <DAGwyn@null.net>
Date: Sun, 21 Oct 2001 11:01:16 GMT
Raw View
Timothy Knox wrote:
> I would suggest the following change:

We're not soliciting proposals for changes.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Timothy Knox <tdk@thelbane.com>
Date: Mon, 15 Oct 2001 17:46:17 GMT
Raw View
I have not been following all of this thread, so forgive me if somebody
has already suggested something similar, which I missed.

I have long felt that the switch statement as it stands in C/C++ has a
problem. While I admire (and use) the ability to have multiple labels
fall through to one common set of code, it leads to much confusion in
teaching this to newcomers. I recall one C/C++ text that spent about
three pages in explaining break and fall-thru. I would suggest the
following change:

Make breaking after each case the default, save when a case label is
bare, ie:

switch (i) {
   case  1:    my_func (i);     /* break automatically */
   case  2:                     /* fall through automatically */
   case  3:    your_func (i);   /* break automatically */
   default:    error_func (i);
};

In addition, I would add an explicit 'fallthru' keyword, as follows:
switch (i) {
   case  1:    my_func (i);            /* break automatically */
   case  2:    our_func (i); fallthru; /* fall through explicitly */
   case  3:    your_func (i);          /* break automatically */
   default:    error_func (i);
};

Finally, in order to make this work transparently with existing C/C++
code, I would add the following logic to the compiler:

Assume new-style 'switch' behaviour for each switch statement
encountered, UNLESS that switch statement has an explicit 'break'
statement, in which case, compile with legacy behaviour. Also, have a
legacy switch (akin to gcc's --traditional) that inverts the sense (ie
Assume old style behaviour unless the code has an explicit fallthru
keyword).

This would allow old code (with its explicit breaks) to work unchanged,
whilst allowing new code to use a (to me) simpler behaviour, that is
easier to teach, and less confusing to the average C/C++ programmer.
--
Timothy Knox
<mailto:tdk@thelbane.com>
"State Farm. Why do you ask?"

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: James Dennett <jdennett@acm.org>
Date: Mon, 15 Oct 2001 19:16:06 GMT
Raw View
Timothy Knox wrote:
> Assume new-style 'switch' behaviour for each switch statement
> encountered, UNLESS that switch statement has an explicit 'break'
> statement, in which case, compile with legacy behaviour. Also, have a
> legacy switch (akin to gcc's --traditional) that inverts the sense (ie
> Assume old style behaviour unless the code has an explicit fallthru
> keyword).
>
> This would allow old code (with its explicit breaks) to work unchanged,
> whilst allowing new code to use a (to me) simpler behaviour, that is
> easier to teach, and less confusing to the average C/C++ programmer.
>


This breaks Duff's device, or any other code which uses
fallthrough and *no* breaks in a switch.  I suspect that's
a significant amount of code.

-- James Dennett

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: David Adrien Tanguay <dat@thinkage.ca>
Date: Mon, 15 Oct 2001 22:18:29 GMT
Raw View
James Dennett wrote:
> This breaks Duff's device, or any other code which uses
> fallthrough and *no* breaks in a switch.  I suspect that's
> a significant amount of code.

Let
  case 42 { ... }
be a synonym for
  case 42: { ... } break;

Seems to do what's wanted, simply and backwards-compatibly, but I don't
think there's enough benefit to be worth the bother.
--
David Tanguay          dat@Thinkage.ca          http://www.thinkage.ca/~dat/
Thinkage, Ltd.           Kitchener, Ontario, Canada          [43.24N 80.29W]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gottlobfrege@hotmail.com (Gottlob Frege)
Date: Tue, 16 Oct 2001 09:24:36 GMT
Raw View
David Adrien Tanguay <dat@thinkage.ca> wrote in message news:<3BCB5EDC.97AE8D28@thinkage.ca>...
> James Dennett wrote:
> > This breaks Duff's device, or any other code which uses
> > fallthrough and *no* breaks in a switch.  I suspect that's
> > a significant amount of code.
>
> Let
>   case 42 { ... }
> be a synonym for
>   case 42: { ... } break;
>
> Seems to do what's wanted, simply and backwards-compatibly, but I don't
> think there's enough benefit to be worth the bother.
> --
> David Tanguay          dat@Thinkage.ca          http://www.thinkage.ca/~dat/
> Thinkage, Ltd.           Kitchener, Ontario, Canada          [43.24N 80.29W]
>

"case 42 { }"  should pretty much satisfy everyone's requests. Except
"goto case 42" which can still be done.

actually you would probably need

   case (42) { }

as in (hope I'm at least close to the correct terminology)

   case (const-expr) statement-block

so this would then also be valid:

   case (42) x = 10;

(ie same as "case 42: x = 10; break;" )

But I agree, might not be worth the bother.  I would guess anyone that
has programmed C/C++ for a number of years will say it is not worth
it.  We've already accepted the way it works long ago.  And I'm sure
most of the people involved with standardization have been programming
for years (and thus think it's not worth the bother).  Maybe we should
try to think like new C/C++ programmers some times? or maybe not?


> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: gottlobfrege@hotmail.com (Gottlob Frege)
Date: Tue, 16 Oct 2001 14:40:12 GMT
Raw View
Timothy Knox <tdk@thelbane.com> wrote in message news:<tdk-31E17B.03300215102001@corp-radius.supernews.com>...
>
> Make breaking after each case the default, save when a case label is
> bare, ie:
>
> switch (i) {
>    case  1:    my_func (i);     /* break automatically */
>    case  2:                     /* fall through automatically */
>    case  3:    your_func (i);   /* break automatically */
>    default:    error_func (i);
> };
>
> In addition, I would add an explicit 'fallthru' keyword, as follows:
> switch (i) {
>    case  1:    my_func (i);            /* break automatically */
>    case  2:    our_func (i); fallthru; /* fall through explicitly */
>    case  3:    your_func (i);          /* break automatically */
>    default:    error_func (i);
> };
>

instead of "fallthru" how about (get ready, I kinda think it's ugly)
"goto;"  ie a goto that doesn't go anywhere.  Ugly, but it goes along
with "goto case 3" which is something that I do like (I've done "goto
defaultCase" a few times in the past, although I can't remember why)

switch (i) {
case 1:
   blah();
   goto;   // ie fallthru, without adding a new keyword
case 2:
   morestuff();
   break;
when 3:
   foobar();
   // implicit break, caused by "when", see comments below...
case 4:
   ...
}

> Finally, in order to make this work transparently with existing C/C++
> code, I would add the following logic to the compiler:
>
> Assume new-style 'switch' behaviour for each switch statement
> encountered, UNLESS that switch statement has an explicit 'break'
> statement, in which case, compile with legacy behaviour. Also, have a
> legacy switch (akin to gcc's --traditional) that inverts the sense (ie
> Assume old style behaviour unless the code has an explicit fallthru
> keyword).
>


what about

switch (i) {
case 1:
   do_somestuff();
   if (something)
      break;
//    ^^^^^   note the break
   //else keep going
   do_more_stuff();

case 2: ...

is this old style or new style?  it does have a "break", but not at
the end.  The hueristics might get ugly.

I prefer the previous suggestion (by jacob navia) of a keyword like
"when" to replace "case" when you don't want fall thru.  I doubt that
I would use it, because I do fall thru often enough, and I don't mind
how it works now (which is why I prefer something like "when" that
doesn't break my old code and that I can ignore).

To sum up:
"goto case 3" gets my vote, and I'm sure I would use it
"goto;" is a fallthru suggestion, but I'm not sure whether I like it
"when" gets my vote, but I doubt I'd use it

(and if you have "when", then do you need a fallthru at all? probably
not. Also, of course "when" may or may not be the best keyword.
Anyone think of any others, or a varied syntax on "case" maybe, so
that we do not need to add a new keyword that will conflict with all
my old "when" variables and functions?  even "case when 3" or
something - a context sensitive keyword, hmmm, not sure about that.
Could add a symbol instead "case {} 3:" a bit subtle, etc....)




P.S. is anyone else really watching this thread anymore.  There was no
posts for a month, and now it's back on?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Tue, 16 Oct 2001 19:45:57 GMT
Raw View
In article <3BCB5EDC.97AE8D28@thinkage.ca>, David Adrien Tanguay
<dat@thinkage.ca> writes
>Let
>  case 42 { ... }
>be a synonym for
>  case 42: { ... } break;
>
>Seems to do what's wanted, simply and backwards-compatibly, but I don't
>think there's enough benefit to be worth the bother.

It's only one character away from legal code. It would be better to make
it more different.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Tue, 16 Oct 2001 20:06:21 GMT
Raw View
In article <e6a90917.0110151944.48ad1dae@posting.google.com>, Gottlob
Frege <gottlobfrege@hotmail.com> writes
>And I'm sure
>most of the people involved with standardization have been programming
>for years (and thus think it's not worth the bother).  Maybe we should
>try to think like new C/C++ programmers some times? or maybe not?

If we're going to do that, then there's a lot that should be thrown away
and started again.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Christian Bau <christian.bau@isltd.insignia.com>
Date: Tue, 28 Aug 2001 16:45:00 GMT
Raw View
Nick Maclaren wrote:
>
> In article <Lj5AbdSsCfh7EwuF@romana.davros.org>,
> "Clive D. W. Feather" <clive@on-the-train.demon.co.uk> writes:
> |> In article <8fbd32b9.0108230308.4e168556@posting.google.com>, Michael
> |> Andres <cizarre@gmx.net> writes
> |> >A problem that occurrs very often in practice is a
> |> >missing "break" at the end of a "case block" within
> |> >a switch.
> |>
> |> That depends rather on what "very often in practice" means. For example,
> |> I can't *ever* recall having made this particular mistake. On the other
> |> hand, I do write code with fall-throughs in.
>
> It isn't common, I agree, but I have made it, seen it and
> investigated a problem caused by it.
>
> FAR more common is the lack of any match in a case where the
> case statement does something essential, often caused by an
> set of categories being extended after the switch statement
> was written.  Making the default compulsory would be a more
> effective change, but most useful of all would be to have a
> default default clause of:
>
>     default: abort();

One compiler that I used had a special warning if the switch expression
was an enum, and the explicit case statements covered most, but not all
of the enum values. For example, if you have case statements for 8 of 10
enum values, then a programmer should cover the remaining two enums with
case statements and not with default.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Thu, 30 Aug 2001 15:06:16 GMT
Raw View
In article <8fbd32b9.0108272337.3281f84b@posting.google.com>, Michael
Andres <cizarre@gmx.net> writes
>But what I am saying is, that it can be necessary to accept that
>existing code can be broken in order to have more safety. And
>this is something that already happened to both standards, C++
>and C as well.

"can be" is the correct phrase. You need to analyse both costs and
benefits.

Note that removing implicit int and implicit declarations have very
little downside to them whereas, for example, removing old-style
functions has a much larger impact.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Sun, 26 Aug 2001 03:12:14 GMT
Raw View
In article <HBF.20010824oc8v@bombur.uio.no>, Hallvard B Furuseth
<h.b.furuseth@usit.uio.no> writes
>>   switch (p) {
>>     default:
>>       if (is_a_prime (p))  {
>>         switch (p) {
>>           case 2: case 3: case 5: case 7: case 11: case 13:
>>    (...)

>Your variant runs all numbers through the default: case, then tests
>is_a_prime() and (in case of primes) then checks if p is 2/3/.../13.
>The point of the original code is that it skips the is_xxx(p) tests
>for small numbers.

His code also gets it wrong if p is not one of the explicitly-listed
cases; it doesn't call *any* function.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Sun, 26 Aug 2001 17:50:40 GMT
Raw View
In article <9m59bd$mr$1@pegasus.csx.cam.ac.uk>, Nick Maclaren
<nmm1@cus.cam.ac.uk> writes
>FAR more common is the lack of any match in a case where the
>case statement does something essential, often caused by an
>set of categories being extended after the switch statement
>was written.  Making the default compulsory would be a more
>effective change,

Agreed. At least it would make people think about it, even though:

    default:
        break;

looks a little ugly to my eyes.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Mon, 27 Aug 2001 11:50:33 GMT
Raw View
"James Russell Kuyper Jr." <kuyper@wizard.net> wrote in message news:<3B87A0E7.648735F9@wizard.net>...
> Michael Andres wrote:
> >
> > "Tzvetan Mikov" <ceco@jupiter.com> wrote in message news:<rIih7.7319$%C.12492@news1.frmt1.sfba.home.com>...
>  ...
> > b) Other changes to the language standard, like required
> > prototypes, required explicit int declarations, required
> > return values, etc. broke by far more existing code but
> > have made it into the standard nevertheless.
>
> This has been posted to both the C and C++ newsgroups. So far, mandatory
> prototyping has only made it into C++, and not into C. C++ needs type
> safety far more strongly than C does, which has been the motivating
> force behind most of backwards-incompatible changes that were made to C
> in the process of creating C++. I don't think the motivating force
> behind this proposed change is anywhere near as great.
>

No, mandatory prototyping has made it into C99 as well.

 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Mon, 27 Aug 2001 11:55:09 GMT
Raw View
Barry Margolin wrote:
>=20
> In article <3B860453.B46F28E8@aixigo.de>,
> Daniel Frey  <daniel.frey@aixigo.de> wrote:
> >Michael Andres wrote:
> >>
> >> A problem that occurrs very often in practice is a
> >> missing "break" at the end of a "case block" within
> >> a switch.
> >>
> >> For that reason switch should be changed in a way
> >> that break is *required* at the end of each case
> >> block. (The idea for this comes from C#)
> >
> >IMHO this is not a good idea. I use switch statements with 'return'
> >instead of 'break' and even sometimes, I throw an exception. An exampl=
e:
>=20
> I think the OP would agree that any control-flow statement would be
> acceptable in place of the break.  The point is to catch unintended
> fall-throughs due to programmers forgetting to break out.

And how will you know a function called throws an exception instead of
returning normally? But anyway: If you want to prevent fall-through you
have to break existing code. Why not a simple macro to change the
language to match your (or the OP's) taste?

#define case break;case

should work fine, although *I* won't do such things, but maybe it's an
option for the OP.

Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 27 Aug 2001 16:25:52 GMT
Raw View
Michael Andres wrote:
...
> No, mandatory prototyping has made it into C99 as well.

The only place where prototypes are currently mandatory is in the
standard headers: 7.1.2p1.

6.7.5 still lists

 _direct-declarator_ ( _identifier-listopt_ )

as one of the legal productions for the _direct-declarator_. 6.7.5.3p14
still identifies it as as way of declaring a function providing only
it's identifier list, and permits the list to be empty.

6.8.1p1 sill allows for an optional declaration-list between a
function's declarator and the compound-statement that contains the body
of the function. Paragraph 5 still makes the declaration-list and a
parameter-type-list mutually exclusive. Paragraph 6 still specifies the
rules governing the use of a declaration-list.

The following clauses refer to prototypes in ways that make it clear
that prototypes are optional: 6.2.7p3; 6.5.2.2 paragraphs 2,6,7, and 8;
Annex I, paragraph 2, bullets 8 and 9; Annex J.1 paragraph 1, bullets
36, 37, and 38.

Sections 6.7.5.3p15, 6.9.1p7, Annex J.2 paragraph 1 bullet 73 also make
it clear that function types without parameter type lists are allowed,
though they don't use the term "prototype" explicitly.

Granted - sections 6.11.6 and 6.11.7 mark this as an osolescent feature,
but any implementation that prematurely ceases to support that feature
does not conform to C99. Someone should probably take note of this list
of affected clauses, in order to speed it's removal from the next
version of the standard.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Mon, 27 Aug 2001 16:27:05 GMT
Raw View
In article <8fbd32b9.0108261448.4943918c@posting.google.com>, Michael
Andres <cizarre@gmx.net> writes
>No, mandatory prototyping has made it into C99 as well.

This is false.

Mandatory declaration of functions is there, but not mandatory
prototypes.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Eric Sosman <Eric.Sosman@sun.com>
Date: Mon, 27 Aug 2001 16:27:25 GMT
Raw View
Michael Andres wrote:
>
> "James Russell Kuyper Jr." <kuyper@wizard.net> wrote:
> > [...] So far, mandatory
> > prototyping has only made it into C++, and not into C. [...]
>
> No, mandatory prototyping has made it into C99 as well.

    Can you provide a citation from the C99 Standard to support
this assertion?  I believe you're wrong, and that Kuyper's
statement (as far as it applies to C, anyhow) is correct.

--
Eric.Sosman@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c_expires-2001-10-01@nmhq.net (Niklas Matthies)
Date: Mon, 27 Aug 2001 18:12:53 GMT
Raw View
On Mon, 27 Aug 2001 11:50:33 GMT, Michael Andres <cizarre@gmx.net> wrote:
>  "James Russell Kuyper Jr." <kuyper@wizard.net> wrote in message news:<3B87A0E7.648735F9@wizard.net>...
> > Michael Andres wrote:
> > >
> > > "Tzvetan Mikov" <ceco@jupiter.com> wrote in message news:<rIih7.7319$%C.12492@news1.frmt1.sfba.home.com>...
> >  ...
> > > b) Other changes to the language standard, like required
> > > prototypes, required explicit int declarations, required
> > > return values, etc. broke by far more existing code but
> > > have made it into the standard nevertheless.
> >
> > This has been posted to both the C and C++ newsgroups. So far, mandatory
> > prototyping has only made it into C++, and not into C. C++ needs type
> > safety far more strongly than C does, which has been the motivating
> > force behind most of backwards-incompatible changes that were made to C
> > in the process of creating C++. I don't think the motivating force
> > behind this proposed change is anywhere near as great.
>
>  No, mandatory prototyping has made it into C99 as well.

Not quite. Non-prototype function declarators are marked as an
obsolescent feature, yes, but they are still legal in C99.

-- Niklas Matthies
--
When I was a little kid, I always wanted a bicycle, so I prayed to god
for a bicycle. Then I realized that god doesn't work that way, so I stole
a bicycle and prayed for forgiveness.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: Mon, 27 Aug 2001 19:02:09 GMT
Raw View
I don't think it is possible to change the semantics of the "switch"
because it will break existing code. But one might introduce a new name,
say "cases" and make it behave as one wants, say as follows:

Syntax:
   cases (head_expression) {
     case expression_1: statement_1
     ...
     case expression_n: statement_n
   };
The expression_i's would be evaluated in sequence, and only the first
expression_i with a match to the value of head_expression would cause the
corresponding statement_i to be evaluated.

Instead of
  int k = ...;
  switch (k) {
    case A_1: ... case A_k: expression; break;
    ...
  };
one could use
  cases (true) {
    case (A_1 == k) || ... || (A_n == k): expression;
  };

When a "cases" expression is simple, modern compilers will probably be
able to optimize.

Also note that more general versions of "cases" might be attained by
copying the pattern matching used in languages like Haskell
<http://haskell.org/>.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Hallvard B Furuseth <h.b.furuseth@usit.uio.no>
Date: Mon, 27 Aug 2001 19:05:16 GMT
Raw View
"Clive D. W. Feather" <clive@on-the-train.demon.co.uk> writes:
>In article <9m59bd$mr$1@pegasus.csx.cam.ac.uk>, Nick Maclaren
><nmm1@cus.cam.ac.uk> writes
>> FAR more common is the lack of any match in a case where the
>> case statement does something essential, often caused by an
>> set of categories being extended after the switch statement
>> was written.  Making the default compulsory would be a more
>> effective change,

Yes, `default: abort()' can catch that at run-time, but this change
prohibits `gcc -Wswitch' from catching it at compile-time.
gcc -Wswitch catches `switch(enum_variable)' where not all named
values are handled (either by a case: or by default:).

> Agreed. At least it would make people think about it, even though:
>
>     default:
>         break;
>
> looks a little ugly to my eyes.

Me too, but I imagine that'll go away when I get used to writing one of

      default: break;
      default: _Notreached;
      default: abort();

Then I'll probably just see it as documentation of which values I
expect the switch to receive.

--
Hallvard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Konrad Schwarz <konradDOTschwarz@mchpDOTsiemens.de>
Date: Mon, 27 Aug 2001 19:06:20 GMT
Raw View
Barry Margolin schrieb:
> No one is claiming that fall-through is useless, just that it's much less
> common, so it's a poor default.

I should have claimed that fall-through is more common than some people
might expect, e.g., it is used on a random bit of code I found on the
internet through a search machine just last week.

> Would it be so inconvenient to have to put an explicit "fallthrough"
> statement into your unrolled loop?

It would have doubled the size of that portion of the source code,
as measured in lines of code.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Mon, 27 Aug 2001 21:12:22 GMT
Raw View
Barry Margolin <barmar@genuity.net> wrote in message news:<Fkwh7.38$5%1.2144@burlma1-snr2>...
> I think the OP would agree that any control-flow statement
> would be acceptable in place of the break.

Yes, I agree. I already posted a modified proposal based on
a generalization of that idea:

Message-ID: <8fbd32b9.0108261552.7530c3d6@posting.google.com>
Subject: "PROPOSAL: improved switch, VERSION 2"

(I am not sure if it was a good idea to open a new thread
for the modified proposal.)


> The point is to catch unintended fall-throughs due to
> programmers forgetting to break out.

exactly!


 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Mon, 27 Aug 2001 22:24:58 GMT
Raw View
Daniel Frey <daniel.frey@aixigo.de> wrote in message news:<3B89FF83.469470A8@aixigo.de>...
> Barry Margolin wrote:
> > I think the OP would agree that any control-flow statement would be
> > acceptable in place of the break.  The point is to catch unintended
> > fall-throughs due to programmers forgetting to break out.
>
> And how will you know a function called throws an exception instead
> of returning normally?

Would it be a function that throws this exception always, I
mean would it be a function that returns exclusively by throwing
an exception, or would the function's behaviour rather depend on
a run time condition?
I think the latter case is more likely, right? The thing is that
there are always run time conditions that are beyond a compiler's
control.

There are of course cases in which a function does definitely
not return. In another posting (version 2 of the proposal,
example 5) I have described such a case:
(Message-ID: 8fbd32b9.0108261552.7530c3d6@posting.google.com>
Subject: "PROPOSAL: improved switch, VERSION 2")


> If you want to prevent fall-through you have to break
> existing code.

I think with the proposal (improved switch, VERSION 2) the cases
in which you would have to break existing code are reduced to a
minimum. Some of the prior modifications of the standard broke
probably more code than this proposal would do.

It cannot be a criterion for a modification if you break existing
code or not, instead it is a criterion how expensive the required
modifications are.


 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Barry Margolin <barmar@genuity.net>
Date: Mon, 27 Aug 2001 22:33:31 GMT
Raw View
In article <3B8A0DF1.F5F5683F@mchpDOTsiemens.de>,
Konrad Schwarz  <konradDOTschwarz@mchpDOTsiemens.de> wrote:
>Barry Margolin schrieb:
>> Would it be so inconvenient to have to put an explicit "fallthrough"
>> statement into your unrolled loop?
>
>It would have doubled the size of that portion of the source code,
>as measured in lines of code.

Since some programmers are paid by LOC, I suppose they'd consider it a
feature!

If you use it alot, you can always make a macro that combines the
fallthrough and case statements.

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 27 Aug 2001 23:54:11 GMT
Raw View
Barry Margolin wrote:
>
> In article <3B8A0DF1.F5F5683F@mchpDOTsiemens.de>,
> Konrad Schwarz  <konradDOTschwarz@mchpDOTsiemens.de> wrote:
...
> >It would have doubled the size of that portion of the source code,
> >as measured in lines of code.
>
> Since some programmers are paid by LOC, I suppose they'd consider it a
> feature!

Who is dumb enough to pay by LOC? How much do they pay? Have they gone
broke yet, or is still possible to get on the gravy train?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: comeau@panix.com (Greg Comeau)
Date: Tue, 28 Aug 2001 12:05:14 GMT
Raw View
In article <8fbd32b9.0108261448.4943918c@posting.google.com>,
Michael Andres <cizarre@gmx.net> wrote:
>"James Russell Kuyper Jr." <kuyper@wizard.net> wrote in message news:<3B87A0E7.648735F9@wizard.net>...
>> This has been posted to both the C and C++ newsgroups. So far, mandatory
>> prototyping has only made it into C++, and not into C. ....
>
>No, mandatory prototyping has made it into C99 as well.

This is incorrect.  Mandatory function _declarations_ have
made it in C99, but those declarations need _not_ be prototypes.
--
Greg Comeau                 Countdown to "export": December 1, 2001
Comeau C/C++ ONLINE ==>     http://www.comeaucomputing.com/tryitout
World Class Compilers:  Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Tue, 28 Aug 2001 16:44:30 GMT
Raw View
"James Russell Kuyper Jr." <kuyper@wizard.net> wrote in message news:<3B8A56A4.EF5DF312@wizard.net>...
> Michael Andres wrote:
> ...
> > No, mandatory prototyping has made it into C99 as well.
>

> Sections 6.7.5.3p15, 6.9.1p7, Annex J.2 paragraph 1 bullet 73
> also make it clear that function types without parameter type
> lists are allowed,

You are right, prototypes are not mandatory in C99. A function
requires a declaration before being called, but that doesn't
mean the declaration has to be a prototype. I was wrong.

But what I am saying is, that it can be necessary to accept that
existing code can be broken in order to have more safety. And
this is something that already happened to both standards, C++
and C as well.


 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Fri, 24 Aug 2001 16:32:35 GMT
Raw View
Michael Andres wrote:
>=20
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>=20
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)

IMHO this is not a good idea. I use switch statements with 'return'
instead of 'break' and even sometimes, I throw an exception. An example:

  inline const GraphSetting& signal( const Signal::Direction
signalDirection ) const
  {
     switch( signalDirection ) {
        case Signal::PRIMARY_DOWN:
        case Signal::SECONDARY_DOWN:
           return signalSell_;

        case Signal::PRIMARY_UP:
        case Signal::SECONDARY_UP:
           return signalBuy_;

        default:
           UNREACHABLE; // throws 'unreachable'
     }
  }

> An exception to this should be an empty case block:
>=20
>   // ...
>   case 'c':    // ok, because empty
>   case 'd':    // ...
>                num =3D 2;
>                break;  // break required
>   // ...

What if I add a MACRO that gives a log-message in debug mode and
resolves to nothing in release mode? Consider:

   case 0:
      PRECONDITION( isFirst );
      LOG( "First time called" );
      // Fall through

   case 1:
      doSomething();


Regards, Daniel

--
Daniel Frey

aixigo AG - financial training, research and technology
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Konrad Schwarz <konradDOTschwarz@mchpDOTsiemens.de>
Date: Fri, 24 Aug 2001 16:33:00 GMT
Raw View
The following code snippet, taken from http://burtleburtle.net/bob/hash/doobs.html
provides further anecdotal evidence that fallthrough can be very useful, e.g.,
when unrolling loops.  The code, part of a hash function, reads the bytes of
an (unaligned) array 12 bytes at a time.

  while (len >= 12)
   {
      a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
      b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
      c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
      mix(a,b,c);
      k += 12; len -= 12;
   }

   /*------------------------------------- handle the last 11 bytes */
   c += length;
   switch(len)              /* all the case statements fall through */
   {
   case 11: c+=((ub4)k[10]<<24);
   case 10: c+=((ub4)k[9]<<16);
   case 9 : c+=((ub4)k[8]<<8);
      /* the first byte of c is reserved for the length */
   case 8 : b+=((ub4)k[7]<<24);
   case 7 : b+=((ub4)k[6]<<16);
   case 6 : b+=((ub4)k[5]<<8);
   case 5 : b+=k[4];
   case 4 : a+=((ub4)k[3]<<24);
   case 3 : a+=((ub4)k[2]<<16);
   case 2 : a+=((ub4)k[1]<<8);
   case 1 : a+=k[0];
     /* case 0: nothing left to add */
   }

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Christian Bau <christian.bau@isltd.insignia.com>
Date: Fri, 24 Aug 2001 16:33:42 GMT
Raw View
Tzvetan Mikov wrote:
>
> IMHO a reasonable compromise is to allow a goto to a case label (e.g. "goto
> case 10" ) and at the same time not require a break after a case block. A
> optional diagnostic could be issued by reasonable compilers if the break is
> missing; old code would still compile.

Allowing a statement

 goto case <expression>;

inside a switch statement would be a relatively useful feature, and it
would also be something that I can write in a fall-through case to
indicate to the compiler and to other programmers that I did not forget
a break statement but that I know what I am doing. (Unfortunately,
"continue;" which would have been the obvious candidate cannot be used
as this changes the meaning of some programs).

In C++, where you cannot goto past a constructor, the programmer would
have to take care for that. And there is the question of whether only
constant integer expressions are allowed, and if a constant integer
expression that doesn't match any of the existing cases is allowed.

If this is added to the language, then a compiler could issue a strong
warning if it sees a fall-through case in a source file containing "goto
case" statements.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Geoff Summerhayes" <sNuOmSrPnAoMt@hNoOtSmPaAiMl.com>
Date: Fri, 24 Aug 2001 16:37:43 GMT
Raw View
"Michael Andres" <cizarre@gmx.net> wrote in message
news:8fbd32b9.0108230308.4e168556@posting.google.com...
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)
>

It will break existing code. Although it is highly
recommended to use a break at the end of every case,
I have seen code that relies on falling through as in:

void update(int where)
{
    // skip to where we need updating
    // remember FORTRAN's computed GOTO?
    switch(where)
    {
    case 0:
        // original assumption changed
        // setup secondary stuff
        // and fall through
    case 1:
        // secondary stuff has changed
        // setup ...
    case 2:
       .
       .
       .
    default:
        // recalc the final bit
    }
}

Not the best code by far, but it is out there and
may be a better choice as far as implementation-
dependant optimization goes.

Perhaps requiring that the compiler issue a warning instead
of an error? Don't have a copy of the standard handy so
I'm not sure what it says now. :-(

Geoff



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Barry Margolin <barmar@genuity.net>
Date: Fri, 24 Aug 2001 17:21:12 GMT
Raw View
In article <3b8580c9$0$236$cc9e4d1f@news.dial.pipex.com>,
Stephen Howe <NOSPAMsjhowe@dial.pipex.com> wrote:
>
>"Michael Andres" <cizarre@gmx.net> wrote in message
>news:8fbd32b9.0108230308.4e168556@posting.google.com...
>> A problem that occurrs very often in practice is a
>> missing "break" at the end of a "case block" within
>> a switch.
>>
>> For that reason switch should be changed in a way
>> that break is *required* at the end of each case
>> block. (The idea for this comes from C#)
>
>I don't regard that as "improved" (and nor will I suspect many C
>programmers). It is considerably inconvient to have to use goto to achieve
>fall-through.

Would it be more palateable if there were a new "fallthrough" keyword
rather than a goto?  I dislike the goto because you might enter the wrong
target (e.g. the next case is "case 4" but you write "goto case 5").

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Niclas Granqvist" <niclas.granqvist@uwatec.ch>
Date: Fri, 24 Aug 2001 17:23:26 GMT
Raw View
"Michael Andres" <cizarre@gmx.net> wrote in message
news:8fbd32b9.0108230308.4e168556@posting.google.com...
>A problem that occurrs very often in practice is a
>missing "break" at the end of a "case block" within
>a switch.

This has never been a problem for me. With C++ I also think that
I am writing less switch-case statements and if-statements than before.

> An exception to this should be an empty case block:
>
>   // ...
>   case 'c':    // ok, because empty
>   case 'd':    // ...
>                num = 2;
>                break;  // break required
>   // ...
>
Often when I write my code I write the switch-case with all possibilities.
Often I have a  case with a break a no code in between the case and the
break.
I fail to see why this would generally be ok.


> Running into the next case block should still be
> possible, but by using a special goto syntax.
>
> Example:
>
>   // ...
>   case 'e':    // ...
>                val = 3;
>                // ...
>                goto case 'f';
>                break;
>   case 'f':    // ...
>                break;
>   // ...

I am not at all surprised that Microsoft has "fixed" this with a goto.
They have been the leader of unstructured programming for years with
with VB. I think this is not very inconvenient and requires one row too
much.

Then I would rather introduce a new keywork or something that makes
falltrhrough explicit:

>   // ...
>   case 'e':    // ...
>                val = 3;
>                // ...
>                fallthrough;
>   case 'f':    // ...
>                break;
>   // ...


Best regards,

Niclas

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Fri, 24 Aug 2001 17:23:52 GMT
Raw View
Eric Sosman <Eric.Sosman@sun.com> wrote in message news:<3B854E35.7E6C1333@sun.com>...
>Michael Andres wrote:
>>
>> A problem that occurrs very often in practice is a
>> missing "break" at the end of a "case block" within
>> a switch.
>>
>> For that reason switch should be changed in a way
>> that break is *required* at the end of each case
>> block. (The idea for this comes from C#)
>
> ...
> I suggest you assess the merits of your suggestion
> by implementing it: Start with gcc or another compiler
> for which source is available, modify it in accordance
> with your proposal, and then try out the modified
> compiler on a largish body of existing source code
> from various organizations.
> Interesting metrics from the experiment might be:
>
>     1. The number of latent bugs exposed by the
>        modified compiler

Discovering latent bugs in existing code are indeed the
idea behind using the keyword "switch" instead of a new
one.

>     2. The number of existing source files which
>        needed changes to get them to work with the
>        modified compiler

In order to minimize code changes
- break is suggested to be a requirement instead of defining
  a case syntax that would just not need a terminating break
- empty case blocks behave as they do in the current definition

>     3. The number of brand-new bugs introduced while
>        making the required changes
>

Yes, it would be interesting to test all this. Could anyone
support me in modifying a compiler according to this?


 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Fri, 24 Aug 2001 17:24:06 GMT
Raw View
"Stephen Howe" <NOSPAMsjhowe@dial.pipex.com> wrote in message news:<3b8580c9$0$236$cc9e4d1f@news.dial.pipex.com>...
>"Michael Andres" <cizarre@gmx.net> wrote in message
>news:8fbd32b9.0108230308.4e168556@posting.google.com...
>> A problem that occurrs very often in practice is a
>> missing "break" at the end of a "case block" within
>> a switch.
>>
>> For that reason switch should be changed in a way
>> that break is *required* at the end of each case
>> block. (The idea for this comes from C#)
>
>  I don't regard that as "improved" (and nor will I suspect many C
> programmers). It is considerably inconvient to have to use goto to
> achieve fall-through.

Yes, true, it would be more inconvenient to achieve
the proposed non-empty fall-through. But that might
be acceptable because non-empty fall-through is needed
much less frequently.

The improvement is meant to consist of a step forward
to correctness, as the proposal is supposed to bring
the code towards what a programmer intends it to mean.

- Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "jacob navia" <jacob@jacob.remcomp.fr>
Date: Fri, 24 Aug 2001 17:24:57 GMT
Raw View
I use the fall-through option a lot in my code:
    switch (foo) {
        case A:
            SomePreprocessingForA(foo);
        case B:
            NormalProcessing(foo);
            break;
        ... other switch cases omitted ...
    }

The 'A' case is just a special case of the B case. It needs some hacking,
conveniently encapsulated in "SomePreprocessingForA".

What's wrong with this?

To avoid breaking existing code you could propose:

    switch (foo) {
        when A:
            "when" clause MUST be followed by a break:
        case B:
            "case" clause falls through
    }

This way we would (at least) preserve the old code, that is not broken in my
opinion.




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Barry Margolin <barmar@genuity.net>
Date: Fri, 24 Aug 2001 17:48:10 GMT
Raw View
In article <toasra7urkk012@corp.supernews.com>,
Geoff Summerhayes <sNuOmSrPnAoMt@hNoOtSmPaAiMl.com> wrote:
>It will break existing code.

This proposal would obviously have to be phased in.  If we alert compiler
vendors that it will be put into C0X, they can start issuing warnings
now.  Users who don't want to update their code can continue to run the
compilers in C99 mode and use an option to disable the warning.

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Barry Margolin <barmar@genuity.net>
Date: Fri, 24 Aug 2001 18:16:45 GMT
Raw View
In article <3B860453.B46F28E8@aixigo.de>,
Daniel Frey  <daniel.frey@aixigo.de> wrote:
>Michael Andres wrote:
>>
>> A problem that occurrs very often in practice is a
>> missing "break" at the end of a "case block" within
>> a switch.
>>
>> For that reason switch should be changed in a way
>> that break is *required* at the end of each case
>> block. (The idea for this comes from C#)
>
>IMHO this is not a good idea. I use switch statements with 'return'
>instead of 'break' and even sometimes, I throw an exception. An example:

I think the OP would agree that any control-flow statement would be
acceptable in place of the break.  The point is to catch unintended
fall-throughs due to programmers forgetting to break out.

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Fri, 24 Aug 2001 18:30:59 GMT
Raw View
"Clive D. W. Feather" <clive@on-the-train.demon.co.uk> wrote in message news:<Lj5AbdSsCfh7EwuF@romana.davros.org>...
> In article <8fbd32b9.0108230308.4e168556@posting.google.com>,
> Michael Andres <cizarre@gmx.net> writes
> >A problem that occurrs very often in practice is a
> >missing "break" at the end of a "case block" within
> >a switch.
>
> That depends rather on what "very often in practice" means. For example,
> I can't *ever* recall having made this particular mistake. On the other
> hand, I do write code with fall-throughs in.


If you have to use code written by unexperienced programmers, as it is
likely in a larger project, then you will have to handle this problem
without having made a mistake by yourself.


> >For that reason switch should be changed in a way
> >that break is *required* at the end of each case
> >block. (The idea for this comes from C#)
>
> What if there isn't a "case block" ? For example, consider this code:
>
>     switch (p)
>     default:
>         if (is_a_prime (p))
>             case 2: case 3: case 5: case 7: case 11: case 13:
>                 do_prime_case (p);
>         else if (is_a_square (p))
>             case 4: case 9: case 16:
>                 do_square_case (p);
>         else
>             case 6: case 8: case 10: case 12: case 14: case 15:
>                 do_composite_case (p);
>
> This is perfectly legitimate code; the (perhaps expensive) tests
> are skipped in known common cases. How would you replace it ?

Ok, that's a good point.
As a first attempt to face this I would try to regard it as
nested switches, that is to say it looks like being equivalent to


  switch (p) {
    default:
      if (is_a_prime (p))  {
        switch (p) {
          case 2: case 3: case 5: case 7: case 11: case 13:
              do_prime_case (p);
        }
      }
      else if (is_a_square (p))  {
        switch (p) {
          case 4: case 9: case 16:
              do_square_case (p);
        }
      }
      else  {
        switch (p) {
          case 6: case 8: case 10: case 12: case 14: case 15:
              do_composite_case (p);
        }
      }
  }


Is it equivalent? If it is, then there are still "case blocks".


> Or what about the elegant simplicity of Duff's Device ?
>

Huh?


> >An exception to this should be an empty case block:
>
> In other words, each case can have multiple labels.

right


> >Running into the next case block should still be
> >possible, but by using a special goto syntax.
> >
> >Example:
> >
> >  // ...
> >  case 'e':    // ...
> >               val = 3;
> >               // ...
> >               goto case 'f';
> >               break;
> >  case 'f':    // ...
> >               break;
> >  // ...
>
> But now we have the risk of an error: what if I mistype the
> special jump as "goto case 'g'" ? Would this be allowed ? I
> can see the benefits of being able to jump to any other case,
> though equally it's little different from having an ordinary
> label in there. Or would this special syntax only apply if the
> jump is to the very next case ?
>

Ok, in order to avoid potential new kinds of errors it would
make sense to restrict the special goto syntax to those situations
where it has the purpose to allow a new-syntax-fall-through.


> Can I use it elsewhere ?
>
>     case 'e':
>         if (xxx)
>             goto case 'f';
>         val = 7;
>         break;
>
>     case 'f':
>         val = 4;
>         break;
>

(same answer)



> But what I object to in your suggestion is that it
> destroys the neat style of certain kinds of code:
>
>     case 'A':
>         flag = 1;
>     case 'a':
>         // 20 lines of code
>         break;
>
>     case 'B':
>     case 'b':
>         // 20 lines of code
>         break;
>
>     case 'c':
>         flag = 1;
>     case 'C':
>         // 20 lines of code
>         break;
>
>     case 'D':
>         flag = 1;
>     case 'd':
>         // 20 lines of code
>         break;
>

We all have to sacrifice something. :-)
The above example would look like

  case 'A':
      flag = 1;
      goto case 'a';
      break;

  case 'a':
      // 20 lines of code
      break;

  case 'B':
  case 'b':
      // 20 lines of code
      break;
  .
  .
  .
  etc.



> >In addition to these changes also the semantics of
> >a case block should be modified in a way that the
> >scope for local variables ends at the end of such
> >a block.
> >
> >In other words,
> >
> >  // ...
> >  case 'g':    typex_t x = 4;
> >               // ...
> >               break;
> >  case 'h':    // ...
> >
> >should be identical to
> >
> >  // ...
> >  case 'g': {  typex_t x = 4;
> >               // ...
> >               break;
> >            }
> >  case 'h':    // ...
>
> Why ?
>
> Your first code is already legitimate. The only difference would be the
> scope of the variable x.


No, the first code is *not* legitimate!
It causes a compiler error in line "case 'h'", because x is still
in scope but the initialization of x could be omitted by directly
switching to case 'h'.

Some other examples:

Example 1:
    case 'g':   int i = 3;
                break;
    case 'h':   break;  // illegal: omits initialization of i


Example 2:
    case 'g':   int i;
                break;
    case 'h':   break;  // ok, because i is intended to be uninitialized


Example 3:
    case 'g': { int i = 3;
                // ...
                break;
              }
    case 'h':   break;  // ok, because i does not belong to this scope



 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: nmm1@cus.cam.ac.uk (Nick Maclaren)
Date: Fri, 24 Aug 2001 19:43:43 GMT
Raw View
In article <Lj5AbdSsCfh7EwuF@romana.davros.org>,
"Clive D. W. Feather" <clive@on-the-train.demon.co.uk> writes:
|> In article <8fbd32b9.0108230308.4e168556@posting.google.com>, Michael
|> Andres <cizarre@gmx.net> writes
|> >A problem that occurrs very often in practice is a
|> >missing "break" at the end of a "case block" within
|> >a switch.
|>
|> That depends rather on what "very often in practice" means. For example,
|> I can't *ever* recall having made this particular mistake. On the other
|> hand, I do write code with fall-throughs in.

It isn't common, I agree, but I have made it, seen it and
investigated a problem caused by it.

FAR more common is the lack of any match in a case where the
case statement does something essential, often caused by an
set of categories being extended after the switch statement
was written.  Making the default compulsory would be a more
effective change, but most useful of all would be to have a
default default clause of:

    default: abort();


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email:  nmm1@cam.ac.uk
Tel.:  +44 1223 334761    Fax:  +44 1223 334679

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Fri, 24 Aug 2001 19:43:58 GMT
Raw View
In article <3B864EA9.2DBBBA34@isltd.insignia.com>, Christian Bau
<christian.bau@isltd.insignia.com> writes
>Allowing a statement
>
>       goto case <expression>;
>
>inside a switch statement would be a relatively useful feature, and it
>would also be something that I can write in a fall-through case to
>indicate to the compiler and to other programmers that I did not forget
>a break statement but that I know what I am doing.

However, you then have the risk that the case expression isn't written
correctly.

Better is to use a label for the purpose. So instead of:

    case 1:
        // do some things
        if (condition) goto case 4;
        // do some more
        break;

    case 2:
        // some stuff
        goto case 3:
    case 3:
        // some more stuff
        break;

    case 4:
        // still more stuff
        break;

you could write:

    case 1:
        // do some things
        if (condition) goto case_4;
        // do some more
        break;

    case 2:
        // some stuff
        goto case_3:
    case 3: case_3:
        // some more stuff
        break;

    case 4: case_4:
        // still more stuff
        break;

This way you can use more meaningful labels. Furthermore, an accidental
"goto case 2" instead of "goto case 3" has a good likelihood of being
spotted.

>If this is added to the language, then a compiler could issue a strong
>warning if it sees a fall-through case in a source file containing "goto
>case" statements.

That's the only real benefit I can see.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Mike Schilling <mike.schilling@ebay.sun.com>
Date: Fri, 24 Aug 2001 20:46:58 GMT
Raw View
Nick Maclaren wrote:
>

> FAR more common is the lack of any match in a case where the
> case statement does something essential, often caused by an
> set of categories being extended after the switch statement
> was written.  Making the default compulsory would be a more
> effective change, but most useful of all would be to have a
> default default clause of:
>
>     default: abort();
>

better still owuld be
 default:
     nodefaulthandler();

where nodefaulthandler by default calls abort, but
setnodefaulthandler(void func()) can change the default default
processing.  That is, the default default default behavior is to abort.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Fri, 24 Aug 2001 21:01:41 GMT
Raw View
Michael Andres <cizarre@gmx.net> wrote in message
news:8fbd32b9.0108240055.772eafcc@posting.google.com...

> The improvement is meant to consist of a step forward
> to correctness, as the proposal is supposed to bring
> the code towards what a programmer intends it to mean.

Hrrrmm, that is just a visual improvement in that you won't see "break".

Stephen Howe



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 25 Aug 2001 00:53:57 GMT
Raw View
Michael Andres wrote:
>
> "Clive D. W. Feather" <clive@on-the-train.demon.co.uk> wrote in message news:<Lj5AbdSsCfh7EwuF@romana.davros.org>...
> > In article <8fbd32b9.0108230308.4e168556@posting.google.com>,
...
> > What if there isn't a "case block" ? For example, consider this code:
> >
> >     switch (p)
> >     default:
> >         if (is_a_prime (p))
> >             case 2: case 3: case 5: case 7: case 11: case 13:
> >                 do_prime_case (p);
> >         else if (is_a_square (p))
> >             case 4: case 9: case 16:
> >                 do_square_case (p);
> >         else
> >             case 6: case 8: case 10: case 12: case 14: case 15:
> >                 do_composite_case (p);
> >
> > This is perfectly legitimate code; the (perhaps expensive) tests
> > are skipped in known common cases. How would you replace it ?
>
> Ok, that's a good point.
> As a first attempt to face this I would try to regard it as
> nested switches, that is to say it looks like being equivalent to
>
>   switch (p) {
>     default:
>       if (is_a_prime (p))  {
>         switch (p) {
>           case 2: case 3: case 5: case 7: case 11: case 13:
>               do_prime_case (p);
>         }
>       }
>       else if (is_a_square (p))  {
>         switch (p) {
>           case 4: case 9: case 16:
>               do_square_case (p);
>         }
>       }
>       else  {
>         switch (p) {
>           case 6: case 8: case 10: case 12: case 14: case 15:
>               do_composite_case (p);
>         }
>       }
>   }

That doesn't do the same thing. The outermost switch serves no purpose;
it has no explicit cases, just a default case, a which therefore always
executes. Every case statement is associated eclusively with an inner
switch(). That means that the (presumably expensive) is_a_prime(p)
function always gets called. That was the whole point of the original
example - for any integer from 2 to 16, neither is_a_prime() nor
is_a_square() would be called. With your re-write, is_a_prime() is
always called, and is_a_square() is called any time it fails.

...
> > Or what about the elegant simplicity of Duff's Device ?
> >
>
> Huh?

see <http://www.lysator.liu.se/c/duffs-device.html>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: brangdon@cix.co.uk (Dave Harris)
Date: Sat, 25 Aug 2001 02:29:25 GMT
Raw View
cizarre@gmx.net (Michael Andres) wrote (abridged):
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block.

Difficult without breaking existing code.


> An exception to this should be an empty case block:

I quite often write things like:

    switch (alignType) {
    default: ASSERT( false ); // Fall through.
    case Left: left_align(); break;
    case Center: center_align(); break;
    case Right: right_align(); break;
    //...
    }

Here I rely on the fall-through behaviour to do something reasonable in
the default case, if _NDEBUG is defined or if the ASSERT() is ignored.
(ASSERT is like assert with a few more runtime options, including allowing
failures to be ignored.) Unknown align types are treated as left-aligned -
probably better than doing nothing.

So, even with your "empty block" exception, your proposal would break my
existing code. I expect it would break other people's code, too.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Richard Smith" <richard@ex-parrot.com>
Date: Sat, 25 Aug 2001 02:29:58 GMT
Raw View
"Michael Andres" <cizarre@gmx.net> wrote in message
news:8fbd32b9.0108230308.4e168556@posting.google.com...
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)
>
> Example:
>
>   // ...
>   case 'a':    // ...
>                i = 1;
>                // ...
>                        // <-- missing "break" makes the
>                        // compiler issue an error message
>   case 'b':    // ...
>                break;  // ok
>   // ...

You might want to make this slightly broader, and require it to end with any
unconditional jump statement, i.e. break, continue, goto, return or throw,
so that code like

    case 'a': return id_a;
    case 'b': return id_b;
    case 'c': return id_c;
    // ...

still works.  This would also make your drop through syntax slighly cleaner:

> Example:
>
>   // ...
>   case 'e':    // ...
>                val = 3;
>                // ...
>                goto case 'f';
>                break;
                 ^^^^^   Shouldn't be necessary.

>   case 'f':    // ...
>                break;
>   // ...

I think that the ability to write goto case 'f'; would be a worthy addition
to the language in its own right.  I've often wanted to be able to write
code like

    case 'a': /* Do something specific for case 'a' */  goto case 'c';
    case 'b': /* Do something specific for case 'b' */  goto case 'c';
    case 'c': /* General code */ break;

--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Richard Smith" <richard@ex-parrot.com>
Date: Sat, 25 Aug 2001 02:30:24 GMT
Raw View
"Clive D. W. Feather" <clive@on-the-train.demon.co.uk> wrote in message
news:Lj5AbdSsCfh7EwuF@romana.davros.org...
> In article <8fbd32b9.0108230308.4e168556@posting.google.com>, Michael
> Andres <cizarre@gmx.net> writes

[...]

> >In addition to these changes also the semantics of
> >a case block should be modified in a way that the
> >scope for local variables ends at the end of such
> >a block.
> >
> >In other words,
> >
> >  // ...
> >  case 'g':    typex_t x = 4;
> >               // ...
> >               break;
> >  case 'h':    // ...
> >
> >should be identical to
> >
> >  // ...
> >  case 'g': {  typex_t x = 4;
> >               // ...
> >               break;
> >            }
> >  case 'h':    // ...
>
> Why ?
>
> Your first code is already legitimate. The only difference would be the
> scope of the variable x.

I'm not sure about C, but in C++ the first example is not legal.  [6.7/3]
states "it is possible to transfer into a block, but not in a way that
bypasses declarations with initialization.  A program that jumps (ftnt 77:
The transfer from the condition of a switch statement to a case label is
considered a jump in this respect.) from a point where a local variable with
automatic storage duration is not in scope to a point where it is in scope
is ill-formed unless the variable has POD type and is declared without an
initializer."

--
Richard Smith


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Steve Clamage <clamage@eng.sun.com>
Date: Sat, 25 Aug 2001 02:32:16 GMT
Raw View
On Thu, 23 Aug 2001, Michael Andres wrote:
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)

That would be a fine idea when designing a language without
concern for compatibility.

This change would break significant amounts of existing code.
You would have to demonstrate that the benefits outweigh the
large costs, affecting a huge installed code base. I don't believe
this proposal could get any significant amount of support.

The only feasible (IMHO) alternative would be a new construct
similar to switch that has the properties you want. I would
not expect much support for a second switch-like construct,
but at least it wouldn't break a large fraction of existing
programs.

---
Steve Clamage, stephen.clamage@sun.com


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Sat, 25 Aug 2001 02:33:01 GMT
Raw View
"Tzvetan Mikov" <ceco@jupiter.com> wrote in message news:<rIih7.7319$%C.12492@news1.frmt1.sfba.home.com>...

> I myself have suffered numerous times from a forgotten
> break ...

In a larger project there are usually experienced programmers
as well as programmers with less experience. They all
produce code to be shared by each other, which leads to the
situation that those with more experience have to suffer from
forgotten breaks too.


> Of course, there isn't a slightest chance for a change like
> this to make it into the language, since it would break too
> much existing code.

a) It could as well discover latent bugs in existent code.
b) Other changes to the language standard, like required
prototypes, required explicit int declarations, required
return values, etc. broke by far more existing code but
have made it into the standard nevertheless.


> IMHO a reasonable compromise is to allow a goto to a case label
> (e.g. "goto case 10" ) and at the same time not require a break
> after a case block. A optional diagnostic could be issued by
> reasonable compilers if the break is missing; old code would
> still compile.

Usually compilers offer options to bypass new language standard
features anyway, eg. by taking certain errors as warnings only.
That's why I think it wouldn't make much sense to let the standard
make recommendations about warnings or optional diagnostics to be
issued.
If the standard doesn't clearly determine what has to be regarded
as right or wrong in order to allow a compiler being called
conforming to the standard, then there might not be enough pressure
to implement a new feature at all.


 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Barry Margolin <barmar@genuity.net>
Date: Sat, 25 Aug 2001 02:33:31 GMT
Raw View
In article <3B861246.3D60EBF6@mchpDOTsiemens.de>,
Konrad Schwarz  <konradDOTschwarz@mchpDOTsiemens.de> wrote:
>The following code snippet, taken from
>http://burtleburtle.net/bob/hash/doobs.html
>provides further anecdotal evidence that fallthrough can be very useful, e.g.,
>when unrolling loops.

No one is claiming that fall-through is useless, just that it's much less
common, so it's a poor default.

Would it be so inconvenient to have to put an explicit "fallthrough"
statement into your unrolled loop?

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Hallvard B Furuseth <h.b.furuseth@usit.uio.no>
Date: Sat, 25 Aug 2001 02:35:13 GMT
Raw View
cizarre@gmx.net (Michael Andres) wrote:
>Clive D. W. Feather <clive@on-the-train.demon.co.uk> wrote in message news:<Lj5AbdSsCfh7EwuF@romana.davros.org>...
>> What if there isn't a "case block" ? For example, consider this code:
>>
>>     switch (p)
>>     default:
>>         if (is_a_prime (p))
>>             case 2: case 3: case 5: case 7: case 11: case 13:
>>         (...)

> Ok, that's a good point.
> As a first attempt to face this I would try to regard it as
> nested switches, that is to say it looks like being equivalent to

>   switch (p) {
>     default:
>       if (is_a_prime (p))  {
>         switch (p) {
>           case 2: case 3: case 5: case 7: case 11: case 13:
>    (...)

That's not at all equivalent, and it can't be rewritten to use nice
blocks.  Which is the point of that example.

Your variant runs all numbers through the default: case, then tests
is_a_prime() and (in case of primes) then checks if p is 2/3/.../13.
The point of the original code is that it skips the is_xxx(p) tests
for small numbers.

>> Or what about the elegant simplicity of Duff's Device ?
> Huh?

See <http://www.lysator.liu.se/c/duffs-device.html>.
See the two code blocks at the end, they are equivalent.

--
Regards,
Hallvard

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Stephen Howe" <SPAMstephen.howeGUARD@tnsofres.com>
Date: Sat, 25 Aug 2001 02:35:52 GMT
Raw View
Barry Margolin <barmar@genuity.net> wrote in message
news:XBgh7.19$5%1.1133@burlma1-snr2...
> In article <3b8580c9$0$236$cc9e4d1f@news.dial.pipex.com>,
> Stephen Howe <NOSPAMsjhowe@dial.pipex.com> wrote:
> >
> >"Michael Andres" <cizarre@gmx.net> wrote in message
> >news:8fbd32b9.0108230308.4e168556@posting.google.com...
> >> A problem that occurrs very often in practice is a
> >> missing "break" at the end of a "case block" within
> >> a switch.
> >>
> >> For that reason switch should be changed in a way
> >> that break is *required* at the end of each case
> >> block. (The idea for this comes from C#)
> >
> >I don't regard that as "improved" (and nor will I suspect many C
> >programmers). It is considerably inconvient to have to use goto to
achieve
> >fall-through.
>
> Would it be more palateable if there were a new "fallthrough" keyword
> rather than a goto?  I dislike the goto because you might enter the wrong
> target (e.g. the next case is "case 4" but you write "goto case 5").

That is definitely more palateable.

I am also wondering about the scope of  labels like this. If you had several
switches statements in a function, would the scope of  a label be the
function (like a normal goto) or per switch statement? If the scope is a
function then there will be problem with several switch statements with the
same case point.

Stephen Howe





---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Tzvetan Mikov" <ceco@jupiter.com>
Date: Sat, 25 Aug 2001 04:13:26 GMT
Raw View
"Clive D. W. Feather" <clive@on-the-train.demon.co.uk> wrote in message
news:Lj5AbdSsCfh7EwuF@romana.davros.org...

> What if there isn't a "case block" ? For example, consider this code:
>
>     switch (p)
>     default:
>         if (is_a_prime (p))
>             case 2: case 3: case 5: case 7: case 11: case 13:
>                 do_prime_case (p);
>         else if (is_a_square (p))
>             case 4: case 9: case 16:
>                 do_square_case (p);
>         else
>             case 6: case 8: case 10: case 12: case 14: case 15:
>                 do_composite_case (p);
>
> This is perfectly legitimate code; the (perhaps expensive) tests are
> skipped in known common cases. How would you replace it ?

Hm, this code reminds me of the worst examples of goto overusage. How about
if we tried to rewrite it like this:

  switch (p)
  {
  case 2: case 3: case 5: case 7: case 11: case 13:
      do_prime_case( p );
      break;
  case 4: case 9: case 16:
      do_square_case (p);
      break;
  case 6: case 8: case 10: case 12: case 14: case 15:
      do_composite_case (p);
      break;
  default:
      if (is_a_prime (p))
          goto case 2;
      if (is_a_square (p))
          goto case 4;
      goto case 6;
      break;
  }

It seems to me that If I saw both variants for the first time, this one
would be much easier to follow.

-tzvetan






---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Sun, 26 Aug 2001 03:11:34 GMT
Raw View
Michael Andres wrote:
>
> "Tzvetan Mikov" <ceco@jupiter.com> wrote in message news:<rIih7.7319$%C.12492@news1.frmt1.sfba.home.com>...
...
> b) Other changes to the language standard, like required
> prototypes, required explicit int declarations, required
> return values, etc. broke by far more existing code but
> have made it into the standard nevertheless.

This has been posted to both the C and C++ newsgroups. So far, mandatory
prototyping has only made it into C++, and not into C. C++ needs type
safety far more strongly than C does, which has been the motivating
force behind most of backwards-incompatible changes that were made to C
in the process of creating C++. I don't think the motivating force
behind this proposed change is anywhere near as great.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Sun, 26 Aug 2001 03:12:11 GMT
Raw View
In article <8fbd32b9.0108241020.73e4ab2a@posting.google.com>, Michael
Andres <cizarre@gmx.net> writes
>> What if there isn't a "case block" ? For example, consider this code:
>>
>>     switch (p)
>>     default:
>>         if (is_a_prime (p))
>>             case 2: case 3: case 5: case 7: case 11: case 13:
>>                 do_prime_case (p);
>>         else if (is_a_square (p))
>>             case 4: case 9: case 16:
>>                 do_square_case (p);
>>         else
>>             case 6: case 8: case 10: case 12: case 14: case 15:
>>                 do_composite_case (p);
>>
>> This is perfectly legitimate code; the (perhaps expensive) tests
>> are skipped in known common cases. How would you replace it ?
>
>Ok, that's a good point.
>As a first attempt to face this I would try to regard it as
>nested switches, that is to say it looks like being equivalent to
[...]
>Is it equivalent? If it is, then there are still "case blocks".

Huh ?

No, that code is *not* equivalent. If p is 5, it makes a useless call to
is_a_prime. If p is 119, it *fails* to call do_prime_case.

In this example the switch is used as an optimisation. What if the
algorithm turns out to have an oddity with p = 2, such that this should
be treated as composite and not a prime ? Then I can write:

     switch (p)
     default:
         if (is_a_prime (p))
             case 3: case 5: case 7: case 11: case 13:
                 do_prime_case (p);
         else if (is_a_square (p))
             case 4: case 9: case 16:
                 do_square_case (p);
         else
             case 2: // Yes, case 2 should be here and not above
             case 6: case 8: case 10: case 12: case 14: case 15:
                 do_composite_case (p);

or just make it clearer, omitting all the optimisation, with:

     switch (p)
     default:
         if (is_a_prime (p))
             do_prime_case (p);
         else if (is_a_square (p))
             do_square_case (p);
         else
             case 2: // 4 should *not* be treated as a prime
             do_composite_case (p);

(I *don't* want to have to repeat the composite case, or to stick lots
of "p != 2 &&" in the code.)

>> Or what about the elegant simplicity of Duff's Device ?
>Huh?

Look it up. It's a real-world optimisation using a switch to find the
correct starting point in an unrolled loop.

>> >Running into the next case block should still be
>> >possible, but by using a special goto syntax.

>> But now we have the risk of an error: what if I mistype the
>> special jump as "goto case 'g'" ?

>Ok, in order to avoid potential new kinds of errors it would
>make sense to restrict the special goto syntax to those situations
>where it has the purpose to allow a new-syntax-fall-through.

In which case it would be better written as "fallthrough" than
"goto case N", surely ?

>> >In addition to these changes also the semantics of
>> >a case block should be modified in a way that the
>> >scope for local variables ends at the end of such
>> >a block.
[...]
>> Your first code is already legitimate. The only difference would be the
>> scope of the variable x.
>
>No, the first code is *not* legitimate!

It's legitimate in C, and I'm reading this in comp.std.c.

>It causes a compiler error in line "case 'h'", because x is still
>in scope but the initialization of x could be omitted by directly
>switching to case 'h'.

So x has an indeterminate value. Big deal.

>Example 1:
>    case 'g':   int i = 3;
>                break;
>    case 'h':   break;  // illegal: omits initialization of i

Legal in C.

>Example 2:
>    case 'g':   int i;
>                break;
>    case 'h':   break;  // ok, because i is intended to be uninitialized

Also legal in C.

>Example 3:
>    case 'g': { int i = 3;
>                // ...
>                break;
>              }
>    case 'h':   break;  // ok, because i does not belong to this scope

Also legal in C.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Thu, 23 Aug 2001 17:53:31 GMT
Raw View
A problem that occurrs very often in practice is a
missing "break" at the end of a "case block" within
a switch.

For that reason switch should be changed in a way
that break is *required* at the end of each case
block. (The idea for this comes from C#)

Example:

  // ...
  case 'a':    // ...
               i = 1;
               // ...
                       // <-- missing "break" makes the
                       // compiler issue an error message
  case 'b':    // ...
               break;  // ok
  // ...


An exception to this should be an empty case block:

  // ...
  case 'c':    // ok, because empty
  case 'd':    // ...
               num = 2;
               break;  // break required
  // ...


Running into the next case block should still be
possible, but by using a special goto syntax.

Example:

  // ...
  case 'e':    // ...
               val = 3;
               // ...
               goto case 'f';
               break;
  case 'f':    // ...
               break;
  // ...



In addition to these changes also the semantics of
a case block should be modified in a way that the
scope for local variables ends at the end of such
a block.

In other words,

  // ...
  case 'g':    typex_t x = 4;
               // ...
               break;
  case 'h':    // ...

should be identical to

  // ...
  case 'g': {  typex_t x = 4;
               // ...
               break;
            }
  case 'h':    // ...





 - M. Andres

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Eric Sosman <Eric.Sosman@sun.com>
Date: Thu, 23 Aug 2001 18:41:59 GMT
Raw View
Michael Andres wrote:
>
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)

    A proposal's chances of adoption are (so I'm told)
considerably enhanced by a demonstration of practicality.
In this case, I suggest you assess the merits of your
suggestion by implementing it: Start with gcc or another
compiler for which source is available, modify it in
accordance with your proposal, and then try out the
modified compiler on a largish body of existing source
code from various organizations.  Interesting metrics
from the experiment might be:

    1. The number of latent bugs exposed by the
 modified compiler

    2. The number of existing source files which
 needed changes to get them to work with the
 modified compiler

    3. The number of brand-new bugs introduced while
 making the required changes

    Just to get an idea of what you're up against, give
thought to Section 0, line 21 of the C9x Rationale:
"Existing code is important, existing imlementations are
not."  The four words prior to the comma merit intense
scrutiny.

--
Eric.Sosman@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Stephen Howe" <NOSPAMsjhowe@dial.pipex.com>
Date: Thu, 23 Aug 2001 22:34:51 GMT
Raw View
"Michael Andres" <cizarre@gmx.net> wrote in message
news:8fbd32b9.0108230308.4e168556@posting.google.com...
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)

I don't regard that as "improved" (and nor will I suspect many C
programmers). It is considerably inconvient to have to use goto to achieve
fall-through.

Stephen Howe


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: juergen@monocerus.demon.co.uk (Juergen Heinzl)
Date: Fri, 24 Aug 2001 00:16:32 GMT
Raw View
In article <8fbd32b9.0108230308.4e168556@posting.google.com>, Michael Andres wrote:
> A problem that occurrs very often in practice is a
> missing "break" at the end of a "case block" within
> a switch.
>
> For that reason switch should be changed in a way
> that break is *required* at the end of each case
> block. (The idea for this comes from C#)
>
> Example:
>
>   // ...
>   case 'a':    // ...
>                i = 1;
>                // ...
>                        // <-- missing "break" makes the
>                        // compiler issue an error message
>   case 'b':    // ...
>                break;  // ok
>   // ...
>
>
> An exception to this should be an empty case block:
>
>   // ...
>   case 'c':    // ok, because empty
>   case 'd':    // ...
>                num = 2;
>                break;  // break required
>   // ...
[-]
What is the rationale behind "an empty case block is correct" compared
to "falling through" is not ?

I may quite well want to ignore 'c', handle 'c' and trigger
the default else ?

> Running into the next case block should still be
> possible, but by using a special goto syntax.
>
> Example:
>
>   // ...
>   case 'e':    // ...
>                val = 3;
>                // ...
>                goto case 'f';
>                break;
>   case 'f':    // ...
>                break;
>   // ...
[-]
    case 'e':    ...
                 goto case 'f';
   object o;
   break;
[-]
Yes, talking C++ now, but it had better work the same, so if o is some
instance, then things become interesting. If no variable declarations
are to be allowed after goto, then though what would it be good for ?

> In addition to these changes also the semantics of
> a case block should be modified in a way that the
> scope for local variables ends at the end of such
> a block.
>
> In other words,
>
>   // ...
>   case 'g':    typex_t x = 4;
>                // ...
>                break;
>   case 'h':    // ...
>
> should be identical to
>
>   // ...
>   case 'g': {  typex_t x = 4;
>                // ...
>                break;
>             }
>   case 'h':    // ...
[-]
So ...
   case 'f' : int x;
              ...
              break;
   case 'g' : {
                int x;
         ...
              }
       break;
... would be suddenly an error ?!

Just asking,
Juergen

--
\ Real name     : Juergen Heinzl                \       no flames      /
 \ EMail Private : juergen@monocerus.demon.co.uk \ send money instead /

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Tzvetan Mikov" <ceco@jupiter.com>
Date: Fri, 24 Aug 2001 09:52:29 GMT
Raw View
"Stephen Howe" <NOSPAMsjhowe@dial.pipex.com> wrote in message
news:3b8580c9$0$236$cc9e4d1f@news.dial.pipex.com...
>
> "Michael Andres" <cizarre@gmx.net> wrote in message
> news:8fbd32b9.0108230308.4e168556@posting.google.com...
> > A problem that occurrs very often in practice is a
> > missing "break" at the end of a "case block" within
> > a switch.
> >
> > For that reason switch should be changed in a way
> > that break is *required* at the end of each case
> > block. (The idea for this comes from C#)
>
> I don't regard that as "improved" (and nor will I suspect many C
> programmers). It is considerably inconvient to have to use goto to achieve
> fall-through.

Inconvinient in what sense? Because it needs more typing? :-) It certainly
makes everything more explicit, obvious and also allows for much more
flexibility.
I myself have suffered numerous times from a forgotten break or from an
extra one when there should have been a fall through. At other times I have
had to put additional labels when several case blocks needed to fall-through
to the same place.

Of course, there isn't a slightest chance for a change like this to make it
into the language, since it would break too much existing code.

IMHO a reasonable compromise is to allow a goto to a case label (e.g. "goto
case 10" ) and at the same time not require a break after a case block. A
optional diagnostic could be issued by reasonable compilers if the break is
missing; old code would still compile.

-tzvetan




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Clive D. W. Feather" <clive@on-the-train.demon.co.uk>
Date: Fri, 24 Aug 2001 09:54:21 GMT
Raw View
In article <8fbd32b9.0108230308.4e168556@posting.google.com>, Michael
Andres <cizarre@gmx.net> writes
>A problem that occurrs very often in practice is a
>missing "break" at the end of a "case block" within
>a switch.

That depends rather on what "very often in practice" means. For example,
I can't *ever* recall having made this particular mistake. On the other
hand, I do write code with fall-throughs in.

>For that reason switch should be changed in a way
>that break is *required* at the end of each case
>block. (The idea for this comes from C#)

What if there isn't a "case block" ? For example, consider this code:

    switch (p)
    default:
        if (is_a_prime (p))
            case 2: case 3: case 5: case 7: case 11: case 13:
                do_prime_case (p);
        else if (is_a_square (p))
            case 4: case 9: case 16:
                do_square_case (p);
        else
            case 6: case 8: case 10: case 12: case 14: case 15:
                do_composite_case (p);

This is perfectly legitimate code; the (perhaps expensive) tests are
skipped in known common cases. How would you replace it ?

Or what about the elegant simplicity of Duff's Device ?

>An exception to this should be an empty case block:

In other words, each case can have multiple labels.

Would you make an exception of the last case in the block ?

>Running into the next case block should still be
>possible, but by using a special goto syntax.
>
>Example:
>
>  // ...
>  case 'e':    // ...
>               val = 3;
>               // ...
>               goto case 'f';
>               break;
>  case 'f':    // ...
>               break;
>  // ...

But now we have the risk of an error: what if I mistype the special jump
as "goto case 'g'" ? Would this be allowed ? I can see the benefits of
being able to jump to any other case, though equally it's little
different from having an ordinary label in there. Or would this special
syntax only apply if the jump is to the very next case ?

Can I use it elsewhere ?

    case 'e':
        if (xxx)
            goto case 'f';
        val = 7;
        break;

    case 'f':
        val = 4;
        break;

But what I object to in your suggestion is that it destroys the neat
style of certain kinds of code:

    case 'A':
        flag = 1;
    case 'a':
        // 20 lines of code
        break;

    case 'B':
    case 'b':
        // 20 lines of code
        break;

    case 'c':
        flag = 1;
    case 'C':
        // 20 lines of code
        break;

    case 'D':
        flag = 1;
    case 'd':
        // 20 lines of code
        break;

[Note carefully that this is *not* a case of "uppercase sets flag,
lowercase doesn't.]

>In addition to these changes also the semantics of
>a case block should be modified in a way that the
>scope for local variables ends at the end of such
>a block.
>
>In other words,
>
>  // ...
>  case 'g':    typex_t x = 4;
>               // ...
>               break;
>  case 'h':    // ...
>
>should be identical to
>
>  // ...
>  case 'g': {  typex_t x = 4;
>               // ...
>               break;
>            }
>  case 'h':    // ...

Why ?

Your first code is already legitimate. The only difference would be the
scope of the variable x.

--
Clive D.W. Feather, writing for himself  | Home: <clive@davros.org>
Tel: +44 20 8371 1138 (work)             | Web:  <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax)            | Work: <clive@demon.net>
Written on my laptop; please observe the Reply-To address

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: cizarre@gmx.net (Michael Andres)
Date: Fri, 24 Aug 2001 09:54:58 GMT
Raw View
juergen@monocerus.demon.co.uk (Juergen Heinzl) wrote in message news:<slrn9ob3t3.cm.juergen@monocerus.demon.co.uk>...
>In article <8fbd32b9.0108230308.4e168556@posting.google.com>,
>Michael Andres wrote:
>> A problem that occurrs very often in practice is a
>> missing "break" at the end of a "case block" within
>> a switch.
>>
>> For that reason switch should be changed in a way
>> that break is *required* at the end of each case
>> block. (The idea for this comes from C#)
>> [...]
>> An exception to this should be an empty case block:
>>
>>   // ...
>>   case 'c':    // ok, because empty
>>   case 'd':    // ...
>>                num = 2;
>>                break;  // break required
>>   // ...
>[-]
>
>What is the rationale behind "an empty case block is correct"
>compared to "falling through" is not ?

Empty case blocks are meant to behave as they do in the current
definition (fall-through).
The intention behind this is to minimize changes on existing
source code when fulfilling the requirements of the suggested
modified syntax: It is likely that empty case blocks are not
written by mistake but behave rather like the programmer intended
them to.

>I may quite well want to ignore 'c', handle 'c' and trigger
>the default else ?

- ignore 'c':
  // ...
  case 'c': break;
  // ...

- handle 'c' (same as 'd'):
  // ...
  case 'c':    // "fall-through"
  case 'd':    // ...
               num = 2;
               break;  // break required
  // ...

- trigger default:
  either: don't write a case statement for 'c'.
  or:     use the modified goto syntax.
          Example:
  // ...
  case 'c': goto default;
            break;
  default:  // ...


>> Running into the next case block should still be
>> possible, but by using a special goto syntax.
>>
>    case 'e':    ...
>                 goto case 'f';
>                 object o;
>                 break;
>[-]
>Yes, talking C++ now, but it had better work the same, so
>if o is some instance, then things become interesting. If
>no variable declarations are to be allowed after goto, then
>though what would it be good for?

The line "object o" would be inaccessable code with an
unconditional goto. But a conditional goto could make sense:

  case 'e':   // ...
              if (/*...*/) goto case 'f';
              object o;
              break;
  case 'f':   // ...


>> In addition to these changes also the semantics of
>> a case block should be modified in a way that the
>> scope for local variables ends at the end of such
>> a block.
>>
>> In other words,
>>
>>   // ...
>>   case 'g':    typex_t x = 4;
>>                // ...
>>                break;
>>   case 'h':    // ...
>>
>> should be identical to
>>
>>   // ...
>>   case 'g': {  typex_t x = 4;
>>                // ...
>>                break;
>>             }
>>   case 'h':    // ...
>[-]
>So ...
>   case 'f' : int x;
>              ...
>              break;
>   case 'g' : {
>                int x;
>        ...
>              }
>      break;
>
>... would be suddenly an error ?!

No, it would be the same as writing

  case 'f': { int x;
              // ...
              break;
            }
  case 'g': {
              {
                int x;
                // ...
              }
              break;
            }
  // ...



 - Michael

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]