Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PROPOSAL: improved switch, VERSION 2

15 views
Skip to first unread message

Michael Andres

unread,
Aug 27, 2001, 7:53:41 AM8/27/01
to
Considering the postings to this thread I have
written a second version of the proposal:


-- Proposal for an improved switch (2nd version) --

- Content:

A typical programming error in conjunction with
the switch statement is an unintentionally missing
break which makes the program run into the next
case label.

This is a proposal for a new syntax that has the
purpose to avoid the error.

The intention of this proposal is *not* to provide
new features for enhanced programming techniques,
instead it focusses on improving the *correctness*
of code that makes use of the switch statement.


- Objectives for the changed syntax:

a: The proposed new syntax should be less
error prone than the current one.
b: Most of the existing code should run without
change.
c: Everything that can be coded with the current
syntax must still be possible with the proposed
new syntax, though it might be necessary to
make some modifications on the code in order
to achieve the same effect.
d: Required changes should not be expensive.
It is not desirable to rewrite too much of
the code. Extensive tests of the modified
code should not be necessary.

- Changes:

The syntax of the current switch statement is
intended to be replaced by the syntax explained
in the following items.


I: A switch statement consists of a list of
"case-blocks".
Each case-block starts with one or more
case-block-labels.
A case-block-label can be either:
- keyword "case" followed by a
constant-expression followed by a colon
or: - keyword "default" followed by a colon
There can be one or no "default"-label.
[Remark: A similar switch syntax is defined
in C#.]


II: The end of a case-block must be formally not
reachable: It leads to a compiler error if
the end of a case-block can be formally reached.


III: Item (II) is not being applied to the last
case-block in a switch.
[Remark: This exception helps keeping existing
code compilable.
Without this exception the syntax would be
more regular, but the chances that existing
code would compile without any change would
be much lower without this.
This exception might be dropped in future
revisions. Therefore it is considered to be
good style to write the code as if this
exception wouldn't exist. Compiler manufacturers
are encouraged to make the compiler issue a
warning if the condition of item (II) is not
fulfilled in the last case-block.]


IV: There is a case-block scope: It begins at the
entry point of the case-block and ends at the
end of the case-block.
[Remark: That means, with the proposed syntax
case 'a': int i = 1;
break;
case 'b': break;
is identical to
case 'a': { int i = 1;
break;
}
case 'b': { break; }
For the current switch syntax there is no such
thing like a case-block scope. Therefore the lines
case 'a': int i = 2;
break;
case 'b': break; // error
wouldn't compile. This can be confusing. On the other hand
case 'b': break;
case 'a': int i = 2;
break; // ok
compiles without error, which demonstrates a dependency
on the order of code that might be unintended.
The lines
case 'c': int i;
// ...
break;
case 'd': int i; // error
// ...
break;
wouldn't compile according to the current switch
syntax neither.
In contrast to the current syntax, the proposed
switch syntax eliminates the dependency on the
order of code and introduces a more local
behaviour.
All of the above examples would compile with
the proposed switch syntax.]


V: A fall-through-statement is introduced. It consists
just of the keyword "fall_thru" and behaves like a
goto to the entry point of the next following
case-block.
A fall_thru can only be used within a case-block.
If fall_thru appears in the statement-list of a
case-block, then it must be the last statement in
the list.
A fall-through-statement does not affect the
case-block scope.
[Remark: With fall_thru the programmers intention
is "documented by code".]


VI: A fall_thru can be used at the end of the last
case-block as well, where it has just the effect
to leave the switch.
[Remark: As the switch would be left at the end
of the last case-block anyway, the fall_thru
would be redundant, just like a break in the last
case-block is redundant.
The rational behind this is to simplify automatic
code generation.]


VII: A new statement with the keyword "fall_thru_switch"
is introduced into the language.
A fall_thru_switch statement has exactly the same
syntax as the current switch statement.
[Remark: fall_thru_switch is introduced because
there are some special coding techniques to which
the proposed switch syntax cannot be applied.
Furthermore fall_thru_switch can simplify adjustments
of existing code to the proposed syntax, though
the switch statement should always be first choice,
if applicable.]


- Impact of the changes:

Example 1:
switch (c) {
case 'a': // ...
break; // ok

case 'b': // ...
throw exception_x();
// ok, because the end of this case-block
// cannot be reached

case 'c': // ...
return; // ok

case 'd': // ...
for(;;)
f();
// ok: because of "for(;;)" the end of
// this case-block can never be reached

case 'e': // ...
goto label_x;
// ok, because end cannot be reached

case 'f': // ...
fall_thru; // works like a goto
// ok, because end cannot be reached

default : // ...
break;
}
label_x: // ...


Example 2:
int i = 0;
switch (c) {
case 'a': ++i;
// error because end of this case-block
// *can* be reached

case 'b': ++i;
break;
// ok because end of this case-block
// can *not* be reached

case 'c': ++i;
// ok because last case-block (see
// item (III))
// But it is regarded to be better
// style to use a "break" here
// too (see remark to item (III)).
}


Example 3:
int i = 0;
switch (c) {
case 'a': ++i;
fall_thru; // works like a goto to the entry
// point of the following case-block
case 'b': ++i; //
fall_thru; // works like a goto to the end of
// the switch statement
}
// at this point: i==2 if c=='a', i==1 if c=='b',
// i==0 in all other cases


Conforming to item (V) fall_thru has to be the
last statement in a statement-list of a case-block
if fall_thru appears in that list.
For that reason the following is illegal:

Example 4:
switch (c) {
case 'd': fall_thru; // illegal
break;

case 'e': // ...
if (condition_x)
fall_thru; // illegal because fall_thru is not the
// last statement in the case-block
// statement-list
// (in this case the if-statement is
// the last one!)
case 'f': // ...
break;
}


Example 5:
switch (c) {
case 'g': exit();
// exit() belongs to the standard but not
// to the language itself. That's why the
// end of this case-block is formally
// reached => error
//
// This would break existing code but the
// error could be detected at compile time!

case 'h': exit();
break; // ok

case 'i': // ...
break;
}

- Michael

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

Florian Weimer

unread,
Aug 27, 2001, 12:26:56 PM8/27/01
to
ciz...@gmx.net (Michael Andres) writes:

> I: A switch statement consists of a list of
> "case-blocks".
> Each case-block starts with one or more
> case-block-labels.
> A case-block-label can be either:
> - keyword "case" followed by a
> constant-expression followed by a colon
> or: - keyword "default" followed by a colon
> There can be one or no "default"-label.
> [Remark: A similar switch syntax is defined
> in C#.]

Could you provide a more formal description of the syntax?


> II: The end of a case-block must be formally not
> reachable: It leads to a compiler error if
> the end of a case-block can be formally reached.

What does 'formally reachable' mean? Please specify. AFAIK, both the
C and C++ standards do not define this term.

> V: A fall-through-statement is introduced. It consists
> just of the keyword "fall_thru" and behaves like a
> goto to the entry point of the next following
> case-block.

"fall_thru" is just ugly.

> A fall-through-statement does not affect the
> case-block scope.

What does that mean?

Clive D. W. Feather

unread,
Aug 27, 2001, 2:13:00 PM8/27/01
to
In article <8fbd32b9.01082...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes

>-- Proposal for an improved switch (2nd version) --

>VII: A new statement with the keyword "fall_thru_switch"


> is introduced into the language.
> A fall_thru_switch statement has exactly the same
> syntax as the current switch statement.

If you're going to do this, then it is far far better to leave *all*
existing code working, and introduce a new keyword "safe_switch". This
can then have cleaner (in your view, anyway) semantics. Anyone who wants
the new semantics can then just go:
#define switch safe_switch

You don't even need a new keyword: "auto switch" or "switch case" or
some such combination could be used.

> c: Everything that can be coded with the current
> syntax must still be possible with the proposed
> new syntax, though it might be necessary to
> make some modifications on the code in order
> to achieve the same effect.

Existing code is important. There is no need to change it if you provide
new facilities.

>I: A switch statement consists of a list of
> "case-blocks".

[...]


>II: The end of a case-block must be formally not
> reachable: It leads to a compiler error if
> the end of a case-block can be formally reached.

Better proposal: since we have a new keyword for these new kinds of
switches, require the block to end with "endcase" or "case break" or
something like that. Then "break" can revert to its meaning of "exit the
innermost loop". You could also do what BCPL does, and allow endcase to
be an action within a case body.

Or find a punctuator that means "gap between case-blocks". "..." comes
to mind. Reaching the end of a case-block means the end of that case
(this is how Algol 68 does it).

That is, the syntax is:

auto-switch: auto switch ( expression ) { case-block-set }

case-block-set: case-block
case-block-set ... case-block

case-block: case-label-set block-item-list

case-label-set: case-label
case-label-set case-label

case-label: case expression :
default :

(block-item-list is defined already in C99). Constraint: there shall not
be a case-label within a case-block's block-item-list except within an
inner switch or auto-switch statement.

>III: Item (II) is not being applied to the last
> case-block in a switch.

Not necessary in a new construct.

>IV: There is a case-block scope: It begins at the
> entry point of the case-block and ends at the
> end of the case-block.

In the new construct this would be reasonable.

> For the current switch syntax there is no such
> thing like a case-block scope. Therefore the lines
> case 'a': int i = 2;
> break;
> case 'b': break; // error
> wouldn't compile.

On the contrary, it is legal C99.

>V: A fall-through-statement is introduced. It consists
> just of the keyword "fall_thru" and behaves like a
> goto to the entry point of the next following
> case-block.

In a new "safe switch", labels and jumps are a better idea.

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

Wilka

unread,
Aug 27, 2001, 3:10:53 PM8/27/01
to
> A typical programming error in conjunction with
> the switch statement is an unintentionally missing
> break which makes the program run into the next
> case label.
>

If you're finding this to be a problem for your projects, why not consider a
tool such as Lint? It will warn about this, along with many other possible
problems.

--
- Wilka

Sef Campstein

unread,
Aug 27, 2001, 3:44:16 PM8/27/01
to
> VII: A new statement with the keyword "fall_thru_switch"
> is introduced into the language.
> A fall_thru_switch statement has exactly the same
> syntax as the current switch statement.
In what way can we make a distinction between the two if it has exactly the
same syntax?

Michael Andres

unread,
Aug 28, 2001, 8:05:38 AM8/28/01
to
Florian Weimer <Florian...@RUS.Uni-Stuttgart.DE> wrote in message news:<tgheut8...@mercury.rus.uni-stuttgart.de>...

> ciz...@gmx.net (Michael Andres) writes:
>
> > I: A switch statement consists of a list of
> > "case-blocks".
> > Each case-block starts with one or more
> > case-block-labels.
> > A case-block-label can be either:
> > - keyword "case" followed by a
> > constant-expression followed by a colon
> > or: - keyword "default" followed by a colon
> > There can be one or no "default"-label.
> > [Remark: A similar switch syntax is defined
> > in C#.]
>
> Could you provide a more formal description of the syntax?

The given description is not only not very formal, it is also
incomplete. Would you like to write a parser for it? We might
then elaborate the details together.


> > II: The end of a case-block must be formally not
> > reachable: It leads to a compiler error if
> > the end of a case-block can be formally reached.
>
> What does 'formally reachable' mean?

"Formally" is supposed to mean: based on the horizon of the
compiler's ability to analyze if it is possible to reach a
point or not:

void example1(void)
{
return;
int i; // compiler can analyze that this point will
// never be reached
i = 0;
}


void example2(void)
{
exit(0);
int i; // compiler can *not* analyze that this point
// will never be reached.
// so, this point is *formally* reachable although
// it will never be reached in the program.
i = 0;
}


> > V: A fall-through-statement is introduced. It consists
> > just of the keyword "fall_thru" and behaves like a
> > goto to the entry point of the next following
> > case-block.
>
> "fall_thru" is just ugly.
>

That was the purpose. The likelyhood to interfere with other
names should be low.


> > A fall-through-statement does not affect the
> > case-block scope.
>
> What does that mean?
>

Contrary to the proposed syntax there is no "case-block scope" in
the current syntax. I wanted to emphasize that the existence of
a "fall_thru" within a case-block doesn't mean that the scope rules
suddenly behave just like in the current syntax.


- Michael

Florian Weimer

unread,
Aug 28, 2001, 10:54:45 AM8/28/01
to
ciz...@gmx.net (Michael Andres) writes:

> > Could you provide a more formal description of the syntax?
>
> The given description is not only not very formal, it is also
> incomplete. Would you like to write a parser for it?

No, I just want to see the syntax.

> > What does 'formally reachable' mean?
>
> "Formally" is supposed to mean: based on the horizon of the
> compiler's ability to analyze if it is possible to reach a
> point or not:

[examples snipped]

You have to specify this concept formally, otherwise implementations
will differ in what they accept as valid in put (the C# spec contains
quite a few similar flaws). For example, quit a few compilers know
that exit() and longjmp() do not return.

--
Florian Weimer Florian...@RUS.Uni-Stuttgart.DE
University of Stuttgart http://cert.uni-stuttgart.de/
RUS-CERT +49-711-685-5973/fax +49-711-685-5898

Michael Andres

unread,
Aug 28, 2001, 10:55:07 AM8/28/01
to
"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message news:<SPrGwJIp...@romana.davros.org>...

> In article <8fbd32b9.01082...@posting.google.com>, Michael
> Andres <ciz...@gmx.net> writes
> >-- Proposal for an improved switch (2nd version) --
>
> >VII: A new statement with the keyword "fall_thru_switch"
> > is introduced into the language.
> > A fall_thru_switch statement has exactly the same
> > syntax as the current switch statement.
>
> If you're going to do this, then it is far far better to leave *all*
> existing code working, and introduce a new keyword "safe_switch".
> ...

Of course it would be much easier to define a syntax based on
a statement with a new keyword. In that case it wouldn't even
be necessary to define it in a way that it takes a break or
something else to jump out.

But the proposal is an attempt to do it the other way.
Because: It is probably by far more difficult to establish
a new programming style (e.g. with a keyword "safe_switch")
than changing the syntax.

Recommending to use a revised switch statement with another
keyword for getting more safety into code, is like telling
someone just to get up one hour earlier in the morning if he
would like to have a daylight-saving time: It just doesn't
take account of the fact that there are things that depend
on each other.

Did the standardization committees issue a recommendation to
make use of explicit int, in cases where someone would like
to have more type safety? No. Instead it was made obligatory.

I think overcoming habits is harder than revising a standard.

And don't forget the documentation! With the proposal you
wouldn't have to rewrite all programming books! Remember you
told me about the coding example of Duff's Device? I found it
finally in an exercise of chapter "expressions and statements"
in Stroustrup's book.

Besides that example there is only one more which wouldn't
compile - it's an example for the fall through behaviour of
switch, together with a recommendation that it would be a
good idea to make a comment if fall through behaviour is
intended. Could there be a better "comment" than writing
fall_thru into the code?

All other examples would conform to the proposed syntax and
compile without error (provided I have not missed any example
in the book).
It would be interesting to check out K&R (ANSI) for this too.

Duff's Device is by the way an interesting example: I looked
at the *original* code too, and I think the original code
wouldn't compile, neither under standard C nor under standard
C++ ...


> Anyone who wants the new semantics can then just go:
> #define switch safe_switch

You will then certainly agree that it would be not more
effort to write
#define switch fall_thru_switch
for getting instant backwards compatibility. :-)

(I wouldn't really recommend that. It should always be more
uncomfortable to use an unsafe version of something. And
writing down the ugly word fall_thru_switch *is* uncomfortable.)


> Existing code is important. There is no need to change it
> if you provide new facilities.

It is important that existing code is correct. Safety is not
a facility.

"Existing code is important" cannot mean to leave any code
written once upon a time just like it is and touch it under
no circumstances no matter if it serves actual needs or not.

And if it is not compatible: What about conversion tools?

An actual need that I see is taking into account that there
are novices writing code. Look at the market: You do not
always have the choice to say you would like to hire
experienced programmers only.

And there is an even more fundamental problem that has
nothing to do with the market: All programmers have to
make experiences before they are experienced programmers.


After all I would like to say that I don't want to get
hysteric about problems concerning missing breaks in a
switch. There are other problems!

But I don't agree with some argumentation. We got to
solve real world issues with a programming language.

Taking into account that there are always novices coding
programs *is* a real world issue.

The chances that existing code runs under the proposals
syntax are not so bad I think. Of course it would be
interesting to have some statistics.


I have already thought about another solution which
would look like

#pragma switch_off_real_world

but I don't like pragmas.

- Michael

Clive D. W. Feather

unread,
Aug 28, 2001, 4:16:09 PM8/28/01
to
In article <8fbd32b9.01082...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes
>> If you're going to do this, then it is far far better to leave *all*
>> existing code working, and introduce a new keyword "safe_switch".
>> ...
>
>Of course it would be much easier to define a syntax based on
>a statement with a new keyword. In that case it wouldn't even
>be necessary to define it in a way that it takes a break or
>something else to jump out.

Right, and you can cleanup any other problems.

>But the proposal is an attempt to do it the other way.
>Because: It is probably by far more difficult to establish
>a new programming style (e.g. with a keyword "safe_switch")
>than changing the syntax.

Not necessarily. Prototypes were introduced into C as a new syntax,
rather than changing the requirements on function definition but not
altering the syntax. People adopted them because of the advantages.

>Recommending to use a revised switch statement with another
>keyword for getting more safety into code, is like telling
>someone just to get up one hour earlier in the morning if he
>would like to have a daylight-saving time: It just doesn't
>take account of the fact that there are things that depend
>on each other.

Which means what ? You are proposing fiddling with the syntax because
some people make errors with an existing construct; you ignore the fact
that some people find that construct very useful. I'm proposing that you
create a new syntax and teach people to use it; those who need the old
construct still have it.

>Did the standardization committees issue a recommendation to
>make use of explicit int, in cases where someone would like
>to have more type safety? No.

Yes, in C90.

>Instead it was made obligatory.

The situations are hardly comparable. Implicit int does not provide any
functionality that explicit int does not; it's merely syntactic sugar.
As such, requiring the explicit int is harmless - existing code can
quickly and easily be changed and the change is trivial; it could even
be automated.

Banning a whole range of switch *semantics*, on the other hand, is much
more significant. You still haven't explained what will happen with
constructs that don't meet the special case of the controlled statement
being a compound statement and the case labels all labelling statements
that are direct elements of that compound.

>I think overcoming habits is harder than revising a standard.

Not always.

>And don't forget the documentation! With the proposal you
>wouldn't have to rewrite all programming books!

Of course you would. All the ones that say "if there's no break, it
falls through", for a start.

>Duff's Device is by the way an interesting example: I looked
>at the *original* code too, and I think the original code
>wouldn't compile, neither under standard C nor under standard
>C++ ...

Checking the copy at <http://www.lysator.liu.se/c/duffs-device.html>, I
can see absolutely nothing in the meat of it that violates C99. The code
uses implicit int and old-style declarations, but the former is trivial
to fix and the latter is legal.

Um, on second thoughts it appears to be undefined behaviour and has been
since the C Standard first came out, despite the fact that "everyone
knows" it works. But the issue involved is nothing to do with switch
statements per se.

>> Existing code is important. There is no need to change it
>> if you provide new facilities.
>
>It is important that existing code is correct. Safety is not
>a facility.

But my existing code *is* correct.

>"Existing code is important" cannot mean to leave any code
>written once upon a time just like it is and touch it under
>no circumstances no matter if it serves actual needs or not.

But it serves my needs quite well. If we're going to have two
constructs, one with the old semantics and one with the new, then the
*new* construct should have the new semantics. That's common-sense.

>An actual need that I see is taking into account that there
>are novices writing code.

So teach them to use the new construct.

>And there is an even more fundamental problem that has
>nothing to do with the market: All programmers have to
>make experiences before they are experienced programmers.

True but irrelevant.

>After all I would like to say that I don't want to get
>hysteric about problems concerning missing breaks in a
>switch. There are other problems!

Indeed.

>The chances that existing code runs under the proposals
>syntax are not so bad I think. Of course it would be
>interesting to have some statistics.

Much of my code would break. I'm sure I'm not the only one.

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

---

Clive D. W. Feather

unread,
Aug 28, 2001, 4:19:26 PM8/28/01
to
In article <8fbd32b9.0108...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes

>> What does 'formally reachable' mean?
>
>"Formally" is supposed to mean: based on the horizon of the
>compiler's ability to analyze if it is possible to reach a
>point or not:

But you need to define this as well.

>void example2(void)
>{
> exit(0);
> int i; // compiler can *not* analyze that this point
> // will never be reached.

Yes, it can. The function exit is part of the Standard and, therefore, a
compiler can know that it never returns. [Yes, "exit" can be a macro,
but this test would be made after preprocessing.]

>> "fall_thru" is just ugly.
>That was the purpose. The likelyhood to interfere with other
>names should be low.

There is a defined way to *ensure* that you don't interfere: use a
reserved name like "_Fall".

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

---

Tzvetan Mikov

unread,
Aug 28, 2001, 7:08:11 PM8/28/01
to

"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message
news:gtEqIigW...@romana.davros.org...

> >Duff's Device is by the way an interesting example: I looked
> >at the *original* code too, and I think the original code
> >wouldn't compile, neither under standard C nor under standard
> >C++ ...
>
> Checking the copy at <http://www.lysator.liu.se/c/duffs-device.html>, I
> can see absolutely nothing in the meat of it that violates C99. The code
> uses implicit int and old-style declarations, but the former is trivial
> to fix and the latter is legal.
>
> Um, on second thoughts it appears to be undefined behaviour and has been
> since the C Standard first came out, despite the fact that "everyone
> knows" it works. But the issue involved is nothing to do with switch
> statements per se.

Why does it have undefined behavior? I looked but I couldn't find anything
suspicious which leads me to believe that I am missing something extremely
obvious.

-tzvetan


Hallvard B Furuseth

unread,
Aug 28, 2001, 8:37:43 PM8/28/01
to
ciz...@gmx.net (Michael Andres) writes:

> IV: There is a case-block scope: It begins at the
> entry point of the case-block and ends at the
> end of the case-block.

No. That is a quiet change to this code:

int j = 0;
switch (i) {
case 1: int j; bar(&j); break;
case 2: baz(&j); break;
}

Currently baz(&j) uses the 2nd j, with implicit {} it will use 1st j.

I think implicit braces would be bad idea even if the new 'fall-thru
switch' got a new name (like 'auto switch') so it didn't break old code,
since the code would _look_ like it has different scope than it has.
C has a some other confusing scope rules, but nothing this blatant.

If you want every case block to have its own scope, I suggest you use
a different syntax and require the braces. E.g.

auto switch (i) {
case (1) {
int j;
bar(&j);
/* might just as well let break; be implicit too */
}
case (2) {
baz(&j);
}
}

A different 'case' syntax also makes it easier to see what kind of
switch you are looking at, if you are looking at a 'case' in a big
switch.


> case 'd': // ...
> for(;;)
> f();
> // ok: because of "for(;;)" the end of
> // this case-block can never be reached
>
> case 'e': // ...

Require a break here. If you begin to demand flow-control
analysis from the compiler, where do you stop?
Should it figure out that this loop will never end?
for (;;) { if (0) break; }
How about this?
int i = 1;
while (i) { }
or this?
if (something) i = 3; else i = 4;
while (i) { }

--
Hallvard

Michael Andres

unread,
Aug 29, 2001, 1:27:22 PM8/29/01
to
Florian Weimer <Florian...@RUS.Uni-Stuttgart.DE> wrote in message news:<tgg0ac4...@mercury.rus.uni-stuttgart.de>...
> ...

> You have to specify this concept formally, otherwise implementations
> will differ in what they accept as valid in put

I see.

> (the C# spec contains quite a few similar flaws).

Could you give an example? I am just curious. As this is
probably out of topic you can send me a mail if you want.

- Michael


======================================= MODERATOR'S COMMENT:
It would be off-topic for both these groups, I suspect.

Michael Andres

unread,
Aug 29, 2001, 1:27:43 PM8/29/01
to
"Sef Campstein" <s...@campst.tmfweb.nl> wrote in message news:<9me1bm$3di$1...@cyan.nl.gxn.net>...

> > VII: A new statement with the keyword "fall_thru_switch"
> > is introduced into the language.
> > A fall_thru_switch statement has exactly the same
> > syntax as the current switch statement.
> In what way can we make a distinction between the two if it
> has exactly the same syntax?

What I was trying to say was that if fall_thru_switch were
integrated in a *new* compiler version then it would behave
like the switch of an *old* compiler.


- Michael

Michael Andres

unread,
Aug 29, 2001, 1:27:35 PM8/29/01
to
"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message news:<gtEqIigW...@romana.davros.org>...

> ...


> you ignore the fact that some people find that construct
> very useful.

No, I don't ignore it: The idea behind "fall_thru_switch" is
that it behaves just like the current construct. Those who
find it useful wouldn't have to change their personal programming
style.

> ...


> Implicit int does not provide any functionality that explicit int
> does not; it's merely syntactic sugar. As such, requiring the
> explicit int is harmless - existing code can quickly and easily be
> changed

But it has to be changed.

> and the change is trivial; it could even be automated.

I thought of automated conversion when I mentioned the conversion
tools in my last posting. (The most trivial kind of conversion
would be to replace the switch by fall_thru_switch.)


> >And don't forget the documentation! With the proposal you
> >wouldn't have to rewrite all programming books!
>
> Of course you would. All the ones that say "if there's no break,
> it falls through", for a start.
>

The compiler would issue an error message as soon as someone
would try to compile a fall through without the keyword "fall_thru".
Similar to a missing "int".


> >> Existing code is important. There is no need to change it
> >> if you provide new facilities.
> >
> >It is important that existing code is correct. Safety is not
> >a facility.
>
> But my existing code *is* correct.

Prove it! :-)


- Michael

Michael Andres

unread,
Aug 29, 2001, 1:28:08 PM8/29/01
to
Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote in message news:<HBF.2001...@bombur.uio.no>...
> ...

> If you want every case block to have its own scope, I suggest
> you use a different syntax and require the braces.

I agree, requiring the braces would be a better idea, because
it makes more obvious to the reader of the code what really
happens.

> ...


> If you begin to demand flow-control analysis from the compiler,
> where do you stop?
> Should it figure out that this loop will never end?
> for (;;) { if (0) break; }
> How about this?
> int i = 1;
> while (i) { }
> or this?
> if (something) i = 3; else i = 4;
> while (i) { }

I see. Doing it based on flow-control analysis has more implications
than I thought it would have at first sight.


- Michael

Clive D. W. Feather

unread,
Aug 30, 2001, 2:54:01 AM8/30/01
to
In article <vvVi7.11214$%C.1...@news1.frmt1.sfba.home.com>, Tzvetan
Mikov <ce...@jupiter.com> writes

>> >Duff's Device is by the way an interesting example:

>> Um, on second thoughts it appears to be undefined behaviour and has been


>> since the C Standard first came out, despite the fact that "everyone
>> knows" it works. But the issue involved is nothing to do with switch
>> statements per se.
>
>Why does it have undefined behavior? I looked but I couldn't find anything
>suspicious which leads me to believe that I am missing something extremely
>obvious.

It is *so* obvious that nobody, including myself, has ever spotted it:
where does the Standard define the behaviour when a loop is jumped into
?

Consider:

if (condition)
{
T: action_t ();
}
else
{
F: action_f ();
}
action_n ();

On a jump to F, the flow of control rules make it clear that execution
consists of action_f followed by action_n. On a jump to T it would be
unclear whether action_f should be executed; luckily, the Standard makes
the explicit statement that it is not.

However, given the code on the left:

while (x > 0) switch (x)
{ {
W: action_w (); case 1: action_1 ();
} case 2: action_2 (); break;
S: action_s ();
case 3: action_3 ();
}

where does it say that, following a jump to W, the code jumps back to
the test ? Flow of control would imply it does not. Compare with the
code on the right, which has *no* requirement to evaluate x after a jump
to S.

James Russell Kuyper Jr.

unread,
Aug 30, 2001, 8:53:35 AM8/30/01
to
"Clive D. W. Feather" wrote:
...

> It is *so* obvious that nobody, including myself, has ever spotted it:
> where does the Standard define the behaviour when a loop is jumped into
> ?
>
> Consider:
>
> if (condition)
> {
> T: action_t ();
> }
> else
> {
> F: action_f ();
> }
> action_n ();
>
> On a jump to F, the flow of control rules make it clear that execution
> consists of action_f followed by action_n. On a jump to T it would be
> unclear whether action_f should be executed; luckily, the Standard makes
> the explicit statement that it is not.
>
> However, given the code on the left:
>
> while (x > 0) switch (x)
> { {
> W: action_w (); case 1: action_1 ();
> } case 2: action_2 (); break;
> S: action_s ();
> case 3: action_3 ();
> }
>
> where does it say that, following a jump to W, the code jumps back to
> the test ? Flow of control would imply it does not. Compare with the
> code on the right, which has *no* requirement to evaluate x after a jump
> to S.

I couldn't find any statements that make the if() case any better
defined than the while() case. Where are you referring to for the "flow
of control" rules? There are only two uses of the term "flow" in the
standard, and neither one seemed helpful.

Douglas A. Gwyn

unread,
Aug 30, 2001, 9:53:55 AM8/30/01
to
"Clive D. W. Feather" wrote:
> However, given the code on the left:
> while (x > 0) switch (x)
> { {
> W: action_w (); case 1: action_1 ();
> } case 2: action_2 (); break;
> S: action_s ();
> case 3: action_3 ();
> }
> where does it say that, following a jump to W, the code jumps back to
> the test ? Flow of control would imply it does not. Compare with the
> code on the right, which has *no* requirement to evaluate x after a jump
> to S.

I'm not concerned with the case on the left, which must be
undefined behavior since not even a human can tell what was
intended without much more context. In the case on the
right, there is no iteration, and the case labels are just
(unexecuted) labels, so it is clear what should happen.

Clive D. W. Feather

unread,
Aug 30, 2001, 11:06:05 AM8/30/01
to
In article <8fbd32b9.01082...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes
>> Implicit int does not provide any functionality that explicit int
>> does not; it's merely syntactic sugar. As such, requiring the
>> explicit int is harmless - existing code can quickly and easily be
>> changed
>
>But it has to be changed.

But the changed code can be used on compilers that don't implement the
new test. And the code has the same meaning on both old and new.

Your proposal involves changing the semantics in an incompatible manner.
No matter which style you want, the same code can't be used on both
"old" and "new" compilers. Since you're proposing a new construct, let
*it* have the new semantics.

>> >And don't forget the documentation! With the proposal you
>> >wouldn't have to rewrite all programming books!
>>
>> Of course you would. All the ones that say "if there's no break,
>> it falls through", for a start.
>
>The compiler would issue an error message as soon as someone
>would try to compile a fall through without the keyword "fall_thru".
>Similar to a missing "int".

You *still* need to rewrite programming books because of the changes.

>> But my existing code *is* correct.
>
>Prove it! :-)

It matches the specification (I wrote both, so I can be sure of that).

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

---

Daniel Frey

unread,
Aug 30, 2001, 12:45:34 PM8/30/01
to
Michael Andres wrote:
>
> Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote in message news:<HBF.2001...@bombur.uio.no>...
> > ...
> > If you want every case block to have its own scope, I suggest
> > you use a different syntax and require the braces.
>
> I agree, requiring the braces would be a better idea, because
> it makes more obvious to the reader of the code what really
> happens.
>
> > ...
> > If you begin to demand flow-control analysis from the compiler,
> > where do you stop?
> > Should it figure out that this loop will never end?
> > for (;;) { if (0) break; }
> > How about this?
> > int i = 1;
> > while (i) { }
> > or this?
> > if (something) i = 3; else i = 4;
> > while (i) { }
>
> I see. Doing it based on flow-control analysis has more implications
> than I thought it would have at first sight.

I wonder if your approach is appropriate for a language like C/C++.
You'd like the provide no default behaviour for the end of a case-block,
instead, you are trying to force the user to explicitly write down what
he wants. While this may increase safety, it is IMO against the basic
structure of the language. The current switch may not be intuitive for
some people, but it is very direct in that it does what if written down
in the code. If there is a break, it is executed. If there is no break,
the program simply continues with the next statement.

Some people seem to have different expectations at the switch statement,
I guess because they think it is some kind of "if / else if / else" -
replacement. If it should turns out to be a mayority and these people
make too much mistakes (which I doubt, but anyway), there are two
options:

a) Provide a new default behaviour. No flow control analysis will be
required, just provide a 'switch' like this:

switch( x ) {
case 0, 1, 2:
something();
// No fall-through here - implicit 'break'

case 3, 4:
something_else();
continue;

case 5:
if( some_condition() )
continue 1;
// No fall-through here!

case 6, default:
something_completely_different();
}

The implicit-break-solution has some impacts you can see above: 'case'
can have multiple values, 'default' can be used as on of these cases,
continue accepts the case values (including 'default') and as it doesn't
make sense the old way: All blocks have their own scope for variables.
Compilers are able to remove non-reachable implicit 'break'-statements
if they can figure out it actually is non-reachable, but if they can't,
it's not a problem and there won't be incompatibilities depending on the
compilers.

b) Your solution which I'd call the explicit-break-solution. As we have
all seen it, I won't repeat it here, but some of it's drawbacks:

- Depending on the compiler's ability to analyse the reachablility of a
block's end, the code is valid or not. Defining rules to create a
standard is hard and prevents further optimizations as compiler
technologies improve.
- All programmers will have to write more code than today or with
solution a). While this can be seen as an advantage, it can also lead to
code that hides the original idea and even worse the code may be slower
(depending on the optimizations of the compiler)
- As your solution is very similar to if( ... ) { ... } else if( ... ) {
... } else if( ... ) { ... } else { ... } I wonder where's the
difference (from the safety you'd like to achive). If someone notices he
makes mistakes when he uses switch, why does he use it anyway? If I
don't understand exceptions, I shouldn't use them. (note: this shouldn't
be taken personal, it is just meant to show that you can use your own
coding style to prevent errors. I do this and I think a lot of people
will agree that it helps :)

Now, especially for the last point there is something that 'switch' can
do that cannot be achived with if/else/...: The compiler can optimize.
At least it is claimed by a lot of people, but I'd like to hear someone
who actually knows it: Does this really lead to better code or are
today's compilers clever enough to provide the same optimizations for
similar if/else/...-constructs? If they are, we can concentrate on the
interaction of the syntax and the programmer, otherwise we need to be
careful not be remove a feature from the language.

Regards, Daniel

--
Daniel Frey

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

Clive D. W. Feather

unread,
Aug 30, 2001, 12:33:49 PM8/30/01
to
In article <3B8E374F...@wizard.net>, James Russell Kuyper Jr.
<kuy...@wizard.net> writes

>> where does it say that, following a jump to W, the code jumps back to
>> the test ?

>I couldn't find any statements that make the if() case any better


>defined than the while() case.

6.8.4#2.

>Where are you referring to for the "flow
>of control" rules? There are only two uses of the term "flow" in the
>standard, and neither one seemed helpful.

They aren't explicitly named that. The commonest phrase used is "order
of execution".

James Kuyper

unread,
Aug 30, 2001, 1:58:30 PM8/30/01
to
"Clive D. W. Feather" wrote:
>
> In article <3B8E374F...@wizard.net>, James Russell Kuyper Jr.
> <kuy...@wizard.net> writes
> >> where does it say that, following a jump to W, the code jumps back to
> >> the test ?
>
> >I couldn't find any statements that make the if() case any better
> >defined than the while() case.
>
> 6.8.4#2.

I think you mean 6.8.4.1#2? (unless the numbering has changed; I'm
posting this from work, and at work I only have a copy of n869.pdf).

OK. I have to agree; [do] while(), for(), and switch() should all have
comparable wording.

Clive D. W. Feather

unread,
Aug 30, 2001, 2:44:23 PM8/30/01
to
In article <HBF.2001...@bombur.uio.no>, Hallvard B Furuseth
<h.b.fu...@usit.uio.no> writes

>Should it figure out that this loop will never end?
> for (;;) { if (0) break; }
>How about this?
> int i = 1;
> while (i) { }
>or this?
> if (something) i = 3; else i = 4;
> while (i) { }

Or this ?

unsigned int a, b, c, n;
do
get_new_values (&a, &b, &c, &n);
while (n <= 2 || pow (a, n) + pow (b, n) != pow (c, n));

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

---

Clive D. W. Feather

unread,
Aug 30, 2001, 4:17:24 PM8/30/01
to
In article <3B8E7EC5...@wizard.net>, James Kuyper
<kuy...@wizard.net> writes

>> 6.8.4#2.
>
>I think you mean 6.8.4.1#2? (unless the numbering has changed;

No (yes

>OK. I have to agree; [do] while(), for(), and switch() should all have
>comparable wording.

Phew: I haven't missed something obvious, then.

Actually, I don't think switch needs it, because switch is merely a
complex goto in disguise. Once you've done it, you carry on the normal
sequence of execution.

Tzvetan Mikov

unread,
Aug 31, 2001, 4:30:01 PM8/31/01
to

"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message
news:R6SWtPzJ...@romana.davros.org...
> [...]

> However, given the code on the left:
>
> while (x > 0) switch (x)
> { {
> W: action_w (); case 1: action_1 ();
> } case 2: action_2 (); break;
> S: action_s ();
> case 3: action_3 ();
> }
>
> where does it say that, following a jump to W, the code jumps back to
> the test ? Flow of control would imply it does not. Compare with the
> code on the right, which has *no* requirement to evaluate x after a jump
> to S.

Hm, I've never thought about this, but then, I am not very good at
interpreting the standard. Doesn't it make sense to define all the flow
control structures only using "if" and "goto"? Your loop on the left then
transforms into:

L1:if (x > 0)
{
W: action_w();
goto L1;
}

and there is no doubt about the behaviour.

-tzvetan


Clive D. W. Feather

unread,
Aug 31, 2001, 5:08:16 PM8/31/01
to
In article <dtSj7.12819$%C.2...@news1.frmt1.sfba.home.com>, Tzvetan
Mikov <ce...@jupiter.com> writes

>> where does it say that, following a jump to W, the code jumps back to
>> the test ?

>Hm, I've never thought about this, but then, I am not very good at


>interpreting the standard. Doesn't it make sense to define all the flow
>control structures only using "if" and "goto"?

That what "everyone knows" it does. Standard-ese wording can be found,
but first we have to realize that there *is* a defect.

Kai Henningsen

unread,
Sep 2, 2001, 12:34:03 AM9/2/01
to
cl...@on-the-train.demon.co.uk (Clive D. W. Feather) wrote on 27.08.01 in <SPrGwJIp...@romana.davros.org>:

> You don't even need a new keyword: "auto switch" or "switch case" or
> some such combination could be used.

"restrict switch".


Kai
--
http://www.westfalen.de/private/khms/
"... by God I *KNOW* what this network is for, and you can't have it."
- Russ Allbery (r...@stanford.edu)

Michael Andres

unread,
Sep 3, 2001, 5:35:27 PM9/3/01
to
kaih=883a$rZH...@khms.westfalen.de (Kai Henningsen) wrote in message news:<883a$rZH...@khms.westfalen.de>...

> cl...@on-the-train.demon.co.uk (Clive D. W. Feather) wrote on 27.08.01 in <SPrGwJIp...@romana.davros.org>:
>
> > You don't even need a new keyword: "auto switch" or "switch case" or
> > some such combination could be used.
>
> "restrict switch".
>

Why not "static switch"? "static" is over-overloaded anyway.

But for a syntax that should be preferred, it should be less typing, even
less than "switch".

Michael Andres

unread,
Sep 3, 2001, 5:35:38 PM9/3/01
to
Daniel Frey <danie...@aixigo.de> wrote in message news:<3B8E019E...@aixigo.de>...

> ...


> If someone notices he makes mistakes when he uses switch, why
> does he use it anyway?

How can programmer A avoid the mistake if he uses code written by
programmer B?


But I agree it looks like the benefits of the proposal would
be too low to justify the costs. (Although it would be
interesting to see statistics about it.) Also, some problems
would not be solved and there would be some new problems.


Ok, plan B:

- "switch" stays like it is.
- Compilers issue a *warning* when they detect fall-through behaviour
in a switch (e.g. based on a missing break or return or throw).
- The warning can be suppressed if fall-through is the intended
behaviour.


Example 1:

// ...
case 'm': // ...
fallthru; // suppresses warning
case 'n': // ...


Example 2:

fallthru switch () // suppresses warnings for the complete switch
// ...


Compilers could be modified to issue this type of warnings
independently
of a standard, but it would not be helpful to have different keywords
for "fallthru" on different platforms.
So, a minimum set of things should be standardized (just like the
keyword, which could be "fallthru" or a combination of "fallthru" and
"_Fallthru" similar to "bool" and "_Bool").

- Michael

David Thompson

unread,
Sep 4, 2001, 11:23:05 AM9/4/01
to
#if IN_THE_WORST_CSC_TRADITION
Clive D. W. Feather <cl...@on-the-train.demon.co.uk> wrote :

> In article <HBF.2001...@bombur.uio.no>, Hallvard B Furuseth
> <h.b.fu...@usit.uio.no> writes
> >Should it figure out that this loop will never end?
....

> Or this ?
>
> unsigned int a, b, c, n;
> do
> get_new_values (&a, &b, &c, &n);
> while (n <= 2 || pow (a, n) + pow (b, n) != pow (c, n));
>
b=0. FLT requires "no solutions over the _nonzero_ integers."
Even with that correction, computer floating point is an even worse
approximation to mathematical reals than computer integers are to
mathematical ones -- and so on all systems I know of:
n = 5 or 6, a = c = 1K, b = 1

--
- David.Thompson 1 now at worldnet.att.net

Daniel Frey

unread,
Sep 4, 2001, 11:23:38 AM9/4/01
to
Michael Andres wrote:
>
> Daniel Frey <danie...@aixigo.de> wrote in message news:<3B8E019E...@aixigo.de>...
>
> > ...
> > If someone notices he makes mistakes when he uses switch, why
> > does he use it anyway?
>
> [...]

>
> Ok, plan B:
>
> - "switch" stays like it is.

Agreed :)

> - Compilers issue a *warning* when they detect fall-through behaviour
> in a switch (e.g. based on a missing break or return or throw).

Could be a good idea if it's optional. What I'm missing is an
opportunity to tell the compiler to enable or disable certain warnings
on certain packages. Foreign libs that where not designed with this
warning in mind will issue to much warnings in large project thus hiding
the real warnings inside their output.

> - The warning can be suppressed if fall-through is the intended
> behaviour.

As we are talking about compilers and not the language anymore, I'd like
to see a compiler-specific extension here. Within your project, you
could add a define for 'fallthru' if you like. This keeps the language
clean and makes it clear that explicit that compiler-dependent
extensions are used. It's again the "how can I know the end is
reached"-thing. For one compiler you'll have to add 'fallthru' as it
cannot detect that a block never reaches it's end while another compiler
may be better in detecting it. I don't think there's an easy way out :)

Regards, Daniel

--
Daniel Frey

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

---

Michael Andres

unread,
Sep 5, 2001, 5:08:36 AM9/5/01
to
Daniel Frey <danie...@aixigo.de> wrote in message news:<3B94832F...@aixigo.de>...
> Michael Andres wrote:
> >
> > Daniel Frey <danie...@aixigo.de> wrote in message news:<3B8E019E.E48 05...@aixigo.de>...

> ...
> >
> > Ok, plan B:
> >
> > - "switch" stays like it is.
> Agreed :)
I expected that answer. :)

> ...


> > - The warning can be suppressed if fall-through is the intended
> > behaviour.
> As we are talking about compilers and not the language anymore,

That is definitely not what I am saying. On the contrary:
A diversification of such a feature depending on the platform
would not be useful. That's why it should become a language
feature.

Of course the warning should be optional, but compilers need
a standardized criterion to differentiate between intended and
unintended code (no matter with which compiler the code was
written originally).

> ...


> It's again the "how can I know the end is reached"-thing. For
> one compiler you'll have to add 'fallthru' as it cannot detect
> that a block never reaches it's end while another compiler may
> be better in detecting it.

The fact that the ability to analyze code, based on static flow
analysis varies from compiler to compiler doesn't mean it is
impossible to define an unambiguous algorithm for the proposed
functioning. Keeping the algorithm simple would probably also
improve readability of the code.

On the other hand I am not sure if this would really be so important.
If a compiler with less sophisticated flow analysis would complain
about a possibly unintended fall through behaviour, it could be
pacified either by adding "fallthru" *or* (depending on the
programmer's intention) something that the compiler would be able
to detect (e.g. "break"). After that, a compiler with a deeper
analysis would be satisfied as well.


- Michael

Clive D. W. Feather

unread,
Sep 5, 2001, 12:46:52 PM9/5/01
to
In article <8fbd32b9.01090...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes

>- "switch" stays like it is.

Good.

>- Compilers issue a *warning* when they detect fall-through behaviour
> in a switch (e.g. based on a missing break or return or throw).

The Standard does not have a concept of "warning".

>- The warning can be suppressed if fall-through is the intended
> behaviour.

>Compilers could be modified to issue this type of warnings
>independently
>of a standard, but it would not be helpful to have different keywords
>for "fallthru" on different platforms.

I'm not convinced that there are anywhere near enough compilers that do
this to make it worthwhile (particularly since such code is legal and
many people think that a "clean" compile is desirable).

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

---

Daniel Frey

unread,
Sep 5, 2001, 12:49:28 PM9/5/01
to
Michael Andres wrote:
>
> Daniel Frey <danie...@aixigo.de> wrote in message news:<3B94832F...@aixigo.de>...
> > Michael Andres wrote:
> > >
> > > Daniel Frey <danie...@aixigo.de> wrote in message news:<3B8E019E.E48 05...@aixigo.de>...
> > ...
> > >
> > > Ok, plan B:
> > >
> > > - "switch" stays like it is.
> > Agreed :)
> I expected that answer. :)
>
> > ...
> > > - The warning can be suppressed if fall-through is the intended
> > > behaviour.
> > As we are talking about compilers and not the language anymore,
>
> That is definitely not what I am saying. On the contrary:
> A diversification of such a feature depending on the platform
> would not be useful. That's why it should become a language
> feature.

Reasonable, but dangerous. See below...

> Of course the warning should be optional, but compilers need
> a standardized criterion to differentiate between intended and
> unintended code (no matter with which compiler the code was
> written originally).
>
> > ...
> > It's again the "how can I know the end is reached"-thing. For
> > one compiler you'll have to add 'fallthru' as it cannot detect
> > that a block never reaches it's end while another compiler may
> > be better in detecting it.
>
> The fact that the ability to analyze code, based on static flow
> analysis varies from compiler to compiler doesn't mean it is
> impossible to define an unambiguous algorithm for the proposed
> functioning. Keeping the algorithm simple would probably also
> improve readability of the code.

But this algorithms seems to be the real problem.

> On the other hand I am not sure if this would really be so important.
> If a compiler with less sophisticated flow analysis would complain
> about a possibly unintended fall through behaviour, it could be
> pacified either by adding "fallthru" *or* (depending on the
> programmer's intention) something that the compiler would be able
> to detect (e.g. "break"). After that, a compiler with a deeper
> analysis would be satisfied as well.

So we are sticked to the lowest common flow analysis. What if a compiler
isn't able to find out that

label: if( ... ) break; else goto label;

will not require 'break;' after it? This makes improvements impossible
and will lead to code that makes me think that there *must* be a way to
reach the final 'break;', otherwise, it won't be there. In my code, I
have a #define UNREACHABLE ... that could help here, but are you willing
to add an "unreachable" to the language, too?

To sum it up: I think your suggestion is reasonable and could be a good
idea, if you manage to find a clear, easy, unambiguous, flexible,
intuitive, extendable description of the flow analysis that doesn't
yield new supprises to the programmer. I've seen enough code like 'i =
i' to suppress compiler warnings (e.g. about unused variables) and I
have seen enough problems resulting from that code (i=i in a template
automatically requires the type of 'i' to have an operator=(). If you
don't have it, you're stuck). I just want to make sure that the number
of these problems doesn't exceed to number of problem resulting from the
current definition of 'switch'.

Regards, Daniel

--
Daniel Frey

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

---

Dave Hansen

unread,
Sep 5, 2001, 11:05:31 PM9/5/01
to
On Mon, 3 Sep 2001 21:35:38 GMT, ciz...@gmx.net (Michael Andres)
wrote:

[...]


>
>Ok, plan B:
>
>- "switch" stays like it is.
>- Compilers issue a *warning* when they detect fall-through behaviour
> in a switch (e.g. based on a missing break or return or throw).
>- The warning can be suppressed if fall-through is the intended
> behaviour.

That's allowed today. Contact your compiler vendor(s).

Or get a good lint. Gimpel's PC-lint behaves like this. The
fallthrough keyword is spelled differently, but I believe it can be
hidden in a #define to make it look the way you want it to...

Regards,

-=Dave
--
Change is inevitable, progress is not.

Barry Margolin

unread,
Sep 5, 2001, 11:06:01 PM9/5/01
to
In article <W3nH+CQF...@romana.davros.org>,

Clive D. W. Feather <cl...@davros.org> wrote:
>In article <8fbd32b9.01090...@posting.google.com>, Michael
>Andres <ciz...@gmx.net> writes
>>- "switch" stays like it is.
>
>Good.
>
>>- Compilers issue a *warning* when they detect fall-through behaviour
>> in a switch (e.g. based on a missing break or return or throw).
>
>The Standard does not have a concept of "warning".

The way standards often accomplish this is by deprecating it. The
implication that a future revision of the standard may remove something
entirely is a strong suggestion that current implementations should warn
about uses. But deprecation is not a promise to remove something, so you
could just keep deprecating it in every revision.

--
Barry Margolin, bar...@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.

Michael Andres

unread,
Sep 6, 2001, 8:30:00 AM9/6/01
to
Daniel Frey <danie...@aixigo.de> wrote in message news:<3B95F1DF...@aixigo.de>...
> ...

> To sum it up: I think your suggestion is reasonable and could be a good
> idea, if you manage to find a clear, easy, unambiguous, flexible,
> intuitive, extendable description of the flow analysis that doesn't
> yield new supprises to the programmer.

That would be the optimum.
I found the following warning option in a compiler:
"possible use of 'identifier' before definition"
This warning would be issued in a case like
for(int i; i < 10; ++i) {
}

The word "possible" implies that the compiler is not always
able to analyze the code. But the warning is a help!


- Michael

Daniel Frey

unread,
Sep 6, 2001, 11:47:15 AM9/6/01
to
Michael Andres wrote:
>
> Daniel Frey <danie...@aixigo.de> wrote in message news:<3B95F1DF...@aixigo.de>...
> > ...
> > To sum it up: I think your suggestion is reasonable and could be a good
> > idea, if you manage to find a clear, easy, unambiguous, flexible,
> > intuitive, extendable description of the flow analysis that doesn't
> > yield new supprises to the programmer.
>
> That would be the optimum.
> I found the following warning option in a compiler:
> "possible use of 'identifier' before definition"
> This warning would be issued in a case like
> for(int i; i < 10; ++i) {
> }
>
> The word "possible" implies that the compiler is not always
> able to analyze the code. But the warning is a help!

If it is right on warning you. If the warning results from situations
where the code is clear, it messes up the output and can be a real pain.
If you have a library (e.g. Roguewave) and it issues thousands of
warnings, you're no longer able to see the warnings of your own code.
And my compiler isn't able to suppress warnings only for given library.
OTOH disabling the warning completely isn't an option for me either as I
want the warning if it's right.

Regards, Daniel

--
Daniel Frey

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

---

Michael Andres

unread,
Sep 6, 2001, 11:46:55 AM9/6/01
to
"Clive D. W. Feather" <cl...@on-the-train.demon.co.uk> wrote in message news:<W3nH+CQF...@romana.davros.org>...

> In article <8fbd32b9.01090...@posting.google.com>, Michael
> Andres <ciz...@gmx.net> writes
> >- The warning can be suppressed if fall-through is the intended
> > behaviour.
> >Compilers could be modified to issue this type of warnings
> >independently
> >of a standard, but it would not be helpful to have different keywords
> >for "fallthru" on different platforms.
>
> I'm not convinced that there are anywhere near enough compilers that do
> this to make it worthwhile (particularly since such code is legal and
> many people think that a "clean" compile is desirable).

I found the following warning option in a compiler:
"style of function definition is now obsolete"
For cases like
example(i)
{
}
the compiler would issue the warning.

The desire for a "clean" compile is certainly very high in a
project with too many of these warnings, and the warning will
probably be disabled in such a project.
But in other projects it can be a useful option. It would be
a help for migration to the other declaration style.


- Michael

Christian Bau

unread,
Sep 6, 2001, 1:40:40 PM9/6/01
to
Daniel Frey wrote:
>
> So we are sticked to the lowest common flow analysis. What if a compiler
> isn't able to find out that
>
> label: if( ... ) break; else goto label;
>
> will not require 'break;' after it? This makes improvements impossible
> and will lead to code that makes me think that there *must* be a way to
> reach the final 'break;', otherwise, it won't be there. In my code, I
> have a #define UNREACHABLE ... that could help here, but are you willing
> to add an "unreachable" to the language, too?

At least there is a precedent now in the Java language. Some amount of
flow analysis is part of the language specification; for example flow
analysis is required to determine that every variable is initialised
before it is used, and the exact algorithm for this analysis is part of
the language (that means any two conforming compilers would agree
whether a variable is initialised or not).

BTW. A Java compiler would determine that control flow in your example
will not proceed to the next statement.

Michael Andres

unread,
Sep 7, 2001, 12:30:51 PM9/7/01
to
Christian Bau <christ...@isltd.insignia.com> wrote in message news:<3B974CD6...@isltd.insignia.com>...

> Daniel Frey wrote:
> >
> > So we are sticked to the lowest common flow analysis. What if a compiler
> > isn't able to find out that
> >
> > label: if( ... ) break; else goto label;
> >
> > will not require 'break;' after it? This makes improvements impossible
> > and will lead to code that makes me think that there *must* be a way to
> > reach the final 'break;', otherwise, it won't be there. In my code, I
> > have a #define UNREACHABLE ... that could help here, but are you willing
> > to add an "unreachable" to the language, too?
>
> At least there is a precedent now in the Java language. Some amount of
> flow analysis is part of the language specification; for example flow
> analysis is required to determine that every variable is initialised
> before it is used, and the exact algorithm for this analysis is part of
> the language (that means any two conforming compilers would agree
> whether a variable is initialised or not).
>
> BTW. A Java compiler would determine that control flow in your example
> will not proceed to the next statement.

The "equivalent" for "unreachable" in the example would be a break at
the end. Right?


- Michael

Michael Andres

unread,
Sep 8, 2001, 5:08:03 AM9/8/01
to
Daniel Frey <danie...@aixigo.de> wrote in message news:<3B976A77...@aixigo.de>...
> ...

> If you have a library (e.g. Roguewave) and it issues thousands of
> warnings, you're no longer able to see the warnings of your own code.
> And my compiler isn't able to suppress warnings only for given library.
> OTOH disabling the warning completely isn't an option for me either as I
> want the warning if it's right.

If there were a standardized way to mark a source file with the
version of the standard under which it was written then this
problem could be avoided.

A compiler could then issue warnings depending on the version info.


- Michael

Michael Andres

unread,
Sep 8, 2001, 5:08:16 AM9/8/01
to
id...@hotmail.com (Dave Hansen) wrote in message news:<3b965541...@News.CIS.DFN.DE>...

> On Mon, 3 Sep 2001 21:35:38 GMT, ciz...@gmx.net (Michael Andres)
> wrote:
>
> [...]
> >
> >Ok, plan B:
> >
> >- "switch" stays like it is.
> >- Compilers issue a *warning* when they detect fall-through behaviour
> > in a switch (e.g. based on a missing break or return or throw).
> >- The warning can be suppressed if fall-through is the intended
> > behaviour.
>
> That's allowed today. Contact your compiler vendor(s).
>
> Or get a good lint. Gimpel's PC-lint behaves like this. The
> fallthrough keyword is spelled differently, but I believe it can be
> hidden in a #define to make it look the way you want it to...
>

Good thing! But a standard is responsible for avoiding things like
different spellings.

A standardized behaviour would be desirable for compilers as well as
for external tools like lint.

I would like to become it part of the standard.


- Michael

Conor O'Neill

unread,
Sep 10, 2001, 4:38:37 PM9/10/01
to
In article <8fbd32b9.01090...@posting.google.com>, Michael
Andres <ciz...@gmx.net> writes
>If there were a standardized way to mark a source file with the
>version of the standard under which it was written then this
>problem could be avoided.
>
>A compiler could then issue warnings depending on the version info.

I like this idea. It works for other things, like HTML / XML. Maybe we
should start doing this in source code to create a de-facto standard...
--
Conor O'Neill, Bristol, UK
Speaking for myself, not my Employer

This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.

Douglas A. Gwyn

unread,
Sep 10, 2001, 4:39:02 PM9/10/01
to
Michael Andres wrote:
> If there were a standardized way to mark a source file with the
> version of the standard under which it was written then this
> problem could be avoided.
> A compiler could then issue warnings depending on the version info.

It doesn't serve the general programming community to tie source
code to specific versions of the language standard. If the
program actually *needs* to take into account the version of the
standard that is supported by the implementation, there is already
a standard predefined macro for the purpose.

David R Tribble

unread,
Sep 11, 2001, 12:27:02 AM9/11/01
to
Clive D. W. Feather wrote:
[on Duff's Device...]
>> Why does it have undefined behavior?
>
> It is *so* obvious that nobody, including myself, has ever spotted it:
> where does the Standard define the behaviour when a loop is jumped
> into?
>
> Consider:
>
> if (condition)
> {
> T: action_t ();
> }
> else
> {
> F: action_f ();
> }
> action_n ();
>
> On a jump to F, the flow of control rules make it clear that execution
> consists of action_f followed by action_n. On a jump to T it would be
> unclear whether action_f should be executed; luckily, the Standard
> makes the explicit statement that it is not.

>
> However, given the code on the left:
>
> while (x > 0) switch (x)
> { {
> W: action_w (); case 1: action_1 ();
> } case 2: action_2 (); break;
> S: action_s ();
> case 3: action_3 ();
> }
>
> where does it say that, following a jump to W, the code jumps back to
> the test ? Flow of control would imply it does not. Compare with the
> code on the right, which has *no* requirement to evaluate x after a
> jump to S.

It seems obvious to me that a label in the body of a loop should not
effect normal looping flow control, whether the label is directly
jumped to or simply flowed into through the top of the loop. The
opposite interpretation would imply that the code following the label
should be duplicated, or at least act like it was, giving two possible
flows through it depending on whether 'goto W' was executed or not;
I think insanity lies down this road.

Perhaps the explicit sentence for 'if' flow should be added to the
description of 'while' in the next revision (and/or as a DR?).


-- David R Tribble, mailto:da...@tribble.com --

Niklas Matthies

unread,
Sep 11, 2001, 3:27:38 AM9/11/01
to
On Tue, 11 Sep 2001 04:27:02 GMT, David R Tribble <da...@tribble.com> wrote:
> Clive D. W. Feather wrote: [on Duff's Device...]
[毽愍

> > However, given the code on the left:
> >
> > while (x > 0) switch (x)
> > { {
> > W: action_w (); case 1: action_1 ();
> > } case 2: action_2 (); break;
> > S: action_s ();
> > case 3: action_3 ();
> > }
> >
> > where does it say that, following a jump to W, the code jumps back to
> > the test ? Flow of control would imply it does not. Compare with the
> > code on the right, which has *no* requirement to evaluate x after a
> > jump to S.
>
> It seems obvious to me that a label in the body of a loop should not
> effect normal looping flow control, whether the label is directly
> jumped to or simply flowed into through the top of the loop. The
> opposite interpretation would imply that the code following the label
> should be duplicated, or at least act like it was, giving two possible
> flows through it depending on whether 'goto W' was executed or not;
> I think insanity lies down this road.

Well, suppose there is a machine code instruction "repeat the following
N instructions (= the body of the loop) until register M becomes 0", and
jumping to label W skips this instruction. Then it would be very natural
for the body of the loop to be executed only once, unconditionally.
There actually are architectures with instructions similar to this.

> Perhaps the explicit sentence for 'if' flow should be added to the
> description of 'while' in the next revision (and/or as a DR?).

Some clarification in the standard would be appropriate.

-- Niklas Matthies
--
You have moved your mouse. Windows must be rebooted for the
changes to take effect.

TransWarpT

unread,
Sep 11, 2001, 12:40:30 PM9/11/01
to
I was right, this is being ignored.

In article <9m5ff1$m5n$1...@wanadoo.fr>, "jacob navia" <ja...@jacob.remcomp.fr>
wrote:

>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.
>

A when clause could be defined in two ways:
1) The programmer must put a break, or other block exit instruction, at the end
of the clause.
2) The compiler automatically inserts a break at the end of the clause.

In either case the compiler would be allowed to dead-strip the break during
optimization.

Orson Bushnell
TransWarp Technologies, LP.

Michael Andres

unread,
Sep 11, 2001, 1:12:51 PM9/11/01
to
"Douglas A. Gwyn" <DAG...@null.net> wrote in message news:<3B9D1CD9...@null.net>...

> Michael Andres wrote:
> > If there were a standardized way to mark a source file with the
> > version of the standard under which it was written then this
> > problem could be avoided.
> > A compiler could then issue warnings depending on the version info.
>
> It doesn't serve the general programming community to tie
> source code to specific versions of the language standard.

If a language standard introduces a new facility then code that
makes use of it is tied to that version of the language standard.

Where exactly do you see the problem?

I have opened a thread "Standardized Standard Version Info". Can you
post your answer to that thread?


- Michael

Michael Andres

unread,
Sep 11, 2001, 1:12:39 PM9/11/01
to
"Conor O'Neill" <ONei...@logica.com> wrote in message news:<khh7oYCw...@adt285.aethos.co.uk>...

> In article <8fbd32b9.01090...@posting.google.com>, Michael
> Andres <ciz...@gmx.net> writes
> >If there were a standardized way to mark a source file with the
> >version of the standard under which it was written then this
> >problem could be avoided.
> >
> >A compiler could then issue warnings depending on the version info.
>
> I like this idea. It works for other things, like HTML / XML. Maybe we
> should start doing this in source code to create a de-facto standard...

I have opened a thread "Standardized Standard Version Info".


- Michael

Clive D. W. Feather

unread,
Sep 11, 2001, 1:43:44 PM9/11/01
to
In article <3B9D921C...@tribble.com>, David R Tribble
<da...@tribble.com> writes

>It seems obvious to me that a label in the body of a loop should not
>effect normal looping flow control, whether the label is directly
>jumped to or simply flowed into through the top of the loop.

That depends on how your loop is implemented. If it's a "test and jump
back" arrangement, then it's "obvious". If the processor has some other
arrangements for looping (e.g. setting a trap at the end of the loop
body), then it isn't.

The rule for "if" flow is obvious for the type of processor that does
test-and-jump. It's *not* obvious if your processor has conditional
opcodes (as, for example, the ARM does).

>Perhaps the explicit sentence for 'if' flow should be added to the
>description of 'while' in the next revision (and/or as a DR?).

DR submitted.

Michael Andres

unread,
Sep 15, 2001, 5:21:59 AM9/15/01
to
trans...@aol.com (TransWarpT) wrote in message news:<20010911124030...@nso-df.aol.com>...

> I was right, this is being ignored.

Sorry, I didn't mean to ignore it.


> In article <9m5ff1$m5n$1...@wanadoo.fr>, "jacob navia" <ja...@jacob.remcomp.fr>
> wrote:
>
> >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.
> >
>
> A when clause could be defined in two ways:
> 1) The programmer must put a break, or other block exit instruction,
> at the end of the clause.
> 2) The compiler automatically inserts a break at the end of the clause.
>
> In either case the compiler would be allowed to dead-strip the break
> during optimization.

My point of view is that the biggest disadvantage of this
suggestion would be that it would still allow to use the other
label type without any complaint.


- Michael

James Russell Kuyper Jr.

unread,
Sep 15, 2001, 8:48:08 AM9/15/01
to
Michael Andres wrote:
...

> My point of view is that the biggest disadvantage of this
> suggestion would be that it would still allow to use the other
> label type without any complaint.

The problem, of course, is that some people consider that to be an
advantage, not a disadvantage.

Michael Andres

unread,
Sep 15, 2001, 12:56:14 PM9/15/01
to
Hallvard B Furuseth <h.b.fu...@usit.uio.no> wrote in message news:<HBF.2001...@bombur.uio.no>...
> ciz...@gmx.net (Michael Andres) writes:
> > case 'd': // ...
> > for(;;)
> > f();
> > // ok: because of "for(;;)" the end of
> > // this case-block can never be reached
> >
> > case 'e': // ...
>
> Require a break here. If you begin to demand flow-control
> analysis from the compiler, where do you stop?

I would like to suggest a better and more detailed definition
of the flow-control analysis based on the comments given in
the postings.

The following is roughly how it might look like. I am not sure
if it is an ideal definition but at least it can be a start
for a discussion.

Some other definitions that are necessary for explaining the
algorithm are provided as well.


- Definition of case-block:

a) Within a statement-sequence that includes case-labelled-statements,
those statements that are between two case-labelled-statements, are
considered to form a partial statement-sequence named case-block.
(case-block type a)

(The beginning statement of the two case-labelled-statements
is meant to be included, the terminating statement of the two
case-labelled-statements is meant to be _not_ included.)

b) All statements that precede the first case-labelled-statement within
the same statement-sequence are considered to form a case-block too.
(case-block type b)

c) Furthermore all statements after the last case-labelled-statement
until the last statement within the same statement-sequence are
considered to form a case-block.
(case-block type c)


- Case labels:

A case-labelled-statement is meant to be:
  case-label statement
(There can be more than one case-label for a statement.)

A case-label is meant to be:
  case constant-expression :
  default :


- Definition of the algorithm for the static flow analysis:

A case-block which precedes a case-labelled-statement (types a
and b of case-block) shall have to be an "obvious-noreturn".

The following are considered to be an obvious-noreturn:

1. a jump out of the enclosing switch
2. a fallthru-statement
3. a throw-statement  [C++ only]
4. a statement-sequence ending in an obvious-noreturn
5. a compound-statement with a statement-sequence ending
   in an obvious-noreturn
6. an if-statement with an else part, in which both branches
   are an obvious-noreturn
7. a try-block in which the try part and all catch parts
   are an obvious-noreturn  [C++ only]

A jump out of the enclosing switch is meant to be one of
the following:

1. a break-statement
2. a return-statement  [seriously: return is considered
   to be obviously not returning! :-) ]
3. a goto-statement that jumps out of the enclosing switch
4. a continue-statement  [if valid at all]


- fallthru-statement:

A fallthru-statement is considered to be like a jump (goto) forward
to a point directly after the last statement of a case-block.
Constraint: A fallthru-statement shall have to be the last statement
in a case-block.

One consequence: A fallthru prior to the first case-label is not
illegal. Another consequence: A fallthru after the last case-label
is not illegal.

Example 1:

  switch (ch) {
    if (any) {
                                fallthru; // like: goto after_last_0;
      case '1':  after_last_0:  f();
fallthru; // like: goto after_last_1;
      case '2':  after_last_1:  fallthru; // like: goto after_last_2;
                 after_last_2:
    }
  }

However, the first and last fallthru in the example are valid but
redundant, so the example is equivalent to
example 2:

  switch (ch) {
    if (any) {
      case '1': f();
fallthru;
      case '2':  ;
    }
  }

which is equivalent to
example 3:

  switch (ch) if (any) case '1': f(); // conforming to suggested syntax!

- fallthru switch:

Fall through behaviour for every case-block (just like it is in the
switch definition of the current standard).

Example 4:

  fallthru switch (ch) {
    case 'a': /* (statement a) */ ; // fall through to statement b
    case 'b': /* (statement b) */ ; // fall through to statement c
    case 'c': /* (statement c) */ ; // fall through to statement d
    case 'd': /* (statement d) */ ;
  }


Some of the simplifications in the algorithm for the flow analysis:
- only goto-statements that *leave* the switch are considered
- break or return, etc. in loops are not considered

Reasons for the simplification:
- easier analysis
- easier to read (sometimes break at the end of a case-block required)

- Michael

TransWarpT

unread,
Sep 17, 2001, 1:32:37 PM9/17/01
to
In the discussion so far there has always been the 'disadvantage' of using the
old style.

In article <8fbd32b9.01091...@posting.google.com>, ciz...@gmx.net

Michael Andres

unread,
Sep 18, 2001, 4:56:34 AM9/18/01
to
"James Russell Kuyper Jr." <kuy...@wizard.net> wrote in message news:<3BA34E08...@wizard.net>...

I know, I know. :-( That lead to the idea to let it basically as
it is and issue warnings instead of errors. At the same time the
cases for a warning were supposed to be reduced to a minimum.

If this is all not acceptable then ... it is difficult.


- Michael

Michael Andres

unread,
Sep 18, 2001, 5:12:28 AM9/18/01
to
trans...@aol.com (TransWarpT) wrote in message news:<20010917133237...@nso-mo.aol.com>...

> In the discussion so far there has always been the 'disadvantage' of
> using the old style.

I tried to find a way to discover those cases where an unintended
usage of the "old style" seems likely. My approach was also based
on the assumption that those cases are rather rare.


- Michael

0 new messages