case labels

B

Ben Pfaff

jacob navia said:
We could write the same switch with less effort if we had:

case 1...3:
//
break;
case 1459...1461:
//
break;

No, not exactly like that:
The ellipsis token exists already. Nothing would be more easy to do.

The ellipsis token exists, but neither case statement above
contains an ellipsis token. Instead, each of them contains a
floating point number followed by characters that do not form
valid tokens.
 
C

christian.bau

why are constant integer expressions required in case labels of the
switch statement? what would be the impact of allowing general integer
expressions instead of constant integer expressions? discuss both user
convenience and implementation aspects?

Consider

switch (i) {
case f (): printf ("f"); break;
case g (): printf ("g"); break;
}

Discuss under user convenience, implementation, and general mental
health aspects.
 
B

Bartc

christian.bau said:
Consider

switch (i) {
case f (): printf ("f"); break;
case g (): printf ("g"); break;
}

Discuss under user convenience, implementation, and general mental
health aspects.

No different to:

if (i==f())
printf("f");
else if (i==g())
printf("g");

which is perfectly legal. It's a question of freedom of expression.
 
C

CBFalconer

christian.bau said:
Consider

switch (i) {
case f (): printf ("f"); break;
case g (): printf ("g"); break;
}

Discuss under user convenience, implementation, and general
mental health aspects.

The function f() is not a constant integer expression. Illegal.
 
K

Keith Thompson

Ben Pfaff said:
No, not exactly like that:


The ellipsis token exists, but neither case statement above
contains an ellipsis token. Instead, each of them contains a
floating point number followed by characters that do not form
valid tokens.

Actually, ``1...3'' and ``1459...1461'' are both valid preprocessor
numbers (pp-numbers) (C99 6.4.8). These preprocessor tokens are
supposed to be converted into tokens in translation phase 7 (C99
5.1.1.2), but the conversion obviously can't succeed. I haven't been
able to find an explicit statement about what's supposed to happen if
a pp-token to token conversion fails; it's at least undefined
behavior.
 
L

lawrence.jones

jacob navia said:
This is correct. But I think allowing case *ranges* would not affect
the generality of the optimization. lcc-win, for instance, generates
several secondary tables in the optimized search tree, when there are
different disjoint ranges of case values.

Yes, case ranges were seriously considered for C99 but ultimately were
rejected because they're less useful than they appear at first glance
and are an open invitation to lead novice programmers astray. For
example, an obvious range is 'A'...'Z', but that doesn't have the
generally expected behavior on many systems (e.g., IBM mainframes use
EBCDIC which has a number of interesting non-alphabetic characters
scattered amongst the letters).

-Larry Jones

I think my cerebellum just fused. -- Calvin
 
K

Keith Thompson

CBFalconer said:
The function f() is not a constant integer expression. Illegal.

Yes, of course it's illegal. That's the point. The example was
intended to illustrate *why* it's illegal (beyond "because the
standard says so").
 
B

Bartc

Keith Thompson said:
Yes, of course it's illegal. That's the point. The example was
intended to illustrate *why* it's illegal (beyond "because the
standard says so").

Maybe I've missed something but how does this example show that it should be
illegal?

I thought possibly all case values need to be considered simultaneously
(difficult with variable expressions) but my C reference says nothing of
this. It does say no two values can be the same (again not easy with
variables), but this is an enhanced switch and the standard cannot cover it.
 
K

Keith Thompson

Bartc said:
Maybe I've missed something but how does this example show that it
should be illegal?

I thought possibly all case values need to be considered
simultaneously (difficult with variable expressions) but my C
reference says nothing of this. It does say no two values can be the
same (again not easy with variables), but this is an enhanced switch
and the standard cannot cover it.

A future version of the language certainly could allow this, but the
example concisely illustrates some of the loose ends that would have
to be tied up in order for it to be well defined.

In an ordinary switch statements, the values of the label expressions
needn't be evaluated at run time. The purpose is to provide a
construct that's more efficient than the equivalent if/else chain.

In this case, do the calls to f() and g() both occur? (If so, then
the resulting code is *slower* than the equivalent if/else chain.) Or
is the call to g() skipped if i == f()? Or can the compiler reverse
the order? And what happens if f()==g()?

Whatever the required semantics turn out to be, there's probably an
equivalent set of if statements that expresses the same semantics more
clearly.
 
O

ozbear

No different to:

if (i==f())
printf("f");
else if (i==g())
printf("g");

which is perfectly legal. It's a question of freedom of expression.

It is "no different to" the corresponding if-then-else ladder if
the semantics behind the proposed construct /said/ that that is
so. An equally valid meaning would be that all case labels are
evaluated and one is chosen based on the one that matched, and
/then/ one would have to describe what happens if two or more
match.

Even if your meaming were chosen the compiler would have to
be careful about any code reordering it might otherwise want to
do for the sake of optimisation, much as it already has to be
so as not to disturb the meaning of fall-thru cases.

Oz
 
J

James Dow Allen

Yes I know there's all sorts of obscure examples where such
a switch would
be ambiguous, but in that case no advance would ever be made.

The "obscure example" IIRC was "f()" -- is this a bizarre
construct? Are there standard C idioms that are ambiguous?

The idea that ambiguous expressions are fine (a "smart"
compiler will guess the most likely or most "friendly"
interpretation) may be in tune with post-modernism,
but it is not the C philosophy.

If you're looking for an overly complex language
with lots of hand-holding, hundreds of complicated
rules to memorize so somebody can save a keystroke,
then c.l.c is the wrong newsgroup.

James Dow Allen
 
H

Harald van Dijk

Actually, ``1...3'' and ``1459...1461'' are both valid preprocessor
numbers (pp-numbers) (C99 6.4.8). These preprocessor tokens are
supposed to be converted into tokens in translation phase 7 (C99
5.1.1.2), but the conversion obviously can't succeed. I haven't been
able to find an explicit statement about what's supposed to happen if a
pp-token to token conversion fails; it's at least undefined behavior.

It's a constraint violation. C99 6.4p1 reads "Each preprocessing token
that is converted to a token shall have the lexical form of a keyword, an
identifier, a constant, a string literal, or a punctuator."
 
P

Peter Nilsson

Harald van D©¦k said:
It's a constraint violation. C99 6.4p1 reads "Each
preprocessing token that is converted to a token shall
have the lexical form of a keyword, an identifier, a
constant, a string literal, or a punctuator."

Nit: 6.4p2.
 
F

Flash Gordon

Yes, case ranges were seriously considered for C99 but ultimately were
rejected because they're less useful than they appear at first glance
and are an open invitation to lead novice programmers astray. For
example, an obvious range is 'A'...'Z', but that doesn't have the
generally expected behavior on many systems (e.g., IBM mainframes use
EBCDIC which has a number of interesting non-alphabetic characters
scattered amongst the letters).

I don't think that is a very good argument against it. The people who
would make that mistake are the people who currently do:
if (c>='A' && c<='Z')
so by forbidding ranges you are not, IMO, reducing errors just
preventing people from using a potentially useful feature.
 
E

Eric Sosman

Flash said:
I don't think that is a very good argument against it. The people who
would make that mistake are the people who currently do:
if (c>='A' && c<='Z')
so by forbidding ranges you are not, IMO, reducing errors just
preventing people from using a potentially useful feature.

If the feature would be so useful, why does every
example trot out 'A' ... 'Z', a useLESS construct? The
gcc documentation leads with that one and goes on to
exhibit 1 ... 5, but does not suggest a context in which
the construct would be appealing.

If someone's got an example where case ranges would
be significantly more useful and expressive, I'd be glad
to see it.
 
B

Bartc

James said:
The "obscure example" IIRC was "f()" -- is this a bizarre
construct? Are there standard C idioms that are ambiguous?

That was from a different post. The ambiguities here are from Eric Sosman's
examples, where perhaps a simple == match may not be the best.
The idea that ambiguous expressions are fine (a "smart"
compiler will guess the most likely or most "friendly"
interpretation) may be in tune with post-modernism,
but it is not the C philosophy.

Read this newsgroup some more. There are plenty of ambiguities!
If you're looking for an overly complex language
with lots of hand-holding, hundreds of complicated
rules

Such as, 'a switch-case expression must be an integer constant'?.
 
F

Flash Gordon

Eric Sosman wrote, On 29/03/08 12:57:
If the feature would be so useful, why does every
example trot out 'A' ... 'Z', a useLESS construct? The

Because they are being stupid?

If you are going to use that example as an argument against it then you
should realise the same argument applies equally against "if" statements.
gcc documentation leads with that one and goes on to
exhibit 1 ... 5, but does not suggest a context in which
the construct would be appealing.

If someone's got an example where case ranges would
be significantly more useful and expressive, I'd be glad
to see it.

I've used the equivalent in Pascal a few times, but I don't have an
example conveniently to hand. However, off the top of my head one
example could be...

switch (ret=foo()) {
case FIRST_ERROR...LAST_ERROR: /* do stuff */
case FIRST_WARNING...LAST_WARNING: /* do stuff */
case FIRST_SUCCESS...LAST_SUCCESS: /* do stuff */
default: /* handle unknown return code */
}

I'm sure there are other situations where it could be potentially
useful. I don't believe there are any situations where it is essential.
 
B

Bartc

Eric said:
If the feature would be so useful, why does every
example trot out 'A' ... 'Z', a useLESS construct? The
gcc documentation leads with that one and goes on to
exhibit 1 ... 5, but does not suggest a context in which
the construct would be appealing.

If someone's got an example where case ranges would
be significantly more useful and expressive, I'd be glad
to see it.

OK, let's try:

switch (cmdcode)
{case 1000..1999: filecmds(); break
case 2000..2499: editcmds(); break;
case 2500..2999: viewcmds(); break
default: misccmds();
};

But whatever example is given, someone will say it can be decomposed into a
combination of if and switch statements. Again, language minimalism for
syntax, but the runtime is some 1000 functions.

The 'A'..'Z' is perfectly OK for an ASCII machine, and there must be a
billion of those so it can be acceptable for such a 'restricted' target.
But for purists, how about a function Asc() that converts a C character code
into ASCII:

case Asc('A')..Asc('Z'): puts("This is one of ABCDEFGHIJKLMNOPQRSTUVWXYZ");
break;

The point is one can adopt any character coding inside a program, so long as
input and output are translated. So why not choose one where alphabetic
character codes are contiguous and sequential?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,813
Messages
2,569,696
Members
45,479
Latest member
QFZErin313

Latest Threads

Top