case labels

C

CBFalconer

Flash said:
Eric Sosman wrote:
.... snip ...


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

Then you have used an illegal Pascal construct, or a poorly
conceived extension in the system. Ranges are also forbidden in
case statements in Pascal. See ISO7185.
 
F

Flash Gordon

CBFalconer wrote, On 29/03/08 15:22:
Then you have used an illegal Pascal construct, or a poorly
conceived extension in the system. Ranges are also forbidden in
case statements in Pascal. See ISO7185.

OK, so it was an extension. This was a long time ago. However it was
still a useful extension and I've yet to see any argument against it
that does not also apply to if statements.
 
H

Harald van Dijk

Then you have used an illegal Pascal construct, or a poorly conceived
extension in the system. Ranges are also forbidden in case statements
in Pascal. See ISO7185.

Ranges are not forbidden in case statements in Pascal. See ISO10206.
Extended Pascal is also standardised.
 
E

Eric Sosman

Bartc said:
OK, let's try:

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

Did you find this (or its equivalent) in an actual
program, or did you simply make it up? My point is not
that a ranged-case switch cannot be imagined, but that
its actual utility is in doubt. Can you find an example
of a real program -- or even a realistic programming
situation -- where case ranges would be helpful?
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:

A programmer who assumes ASCII nowadays is begging
for a tongue-lashing from Anders Ångström, Béla Bartók,
Julius Cæsar, and everyone else through Jan Žižka. The
commonly-used character sets that express these and many
other words contain ASCII as a subset, and the upper-case
letter codes in those sets are not numerically contiguous.

The 'A' ... 'Z' range was useful once upon a time,
when we lived more insularly than we do today. But think:
We're talking about a feature that would be "new," not one
that would have been useful Back In The Day. When you're
writing a new program, is the proposed feature useful?
 
R

Richard Tobin

switch (cmdcode)
{case 1000..1999: filecmds(); break
case 2000..2499: editcmds(); break;
case 2500..2999: viewcmds(); break
default: misccmds();
};
[/QUOTE]
Did you find this (or its equivalent) in an actual
program, or did you simply make it up?

It does seem rather contrived, but I can imagine something similar
for the handling of error codes:

switch(status)
{
case 100..199:
handle_informational(); break;
case 200..299:
handle_success(); break;
case 300..399:
handle_redirection(); break;
case 400..499:
handle_client_error(); break;
case 500..599:
handle_server_error(); break;
}

The numbers and categories are taken from the HTTP protocol:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1

I have several times wanted a range for some of the cases when
processing characters (known to be Unicode, so the encoding doesn't
come into it).

-- Richard
 
J

jacob navia

Eric said:
Did you find this (or its equivalent) in an actual
program, or did you simply make it up? My point is not
that a ranged-case switch cannot be imagined, but that
its actual utility is in doubt. Can you find an example
of a real program -- or even a realistic programming
situation -- where case ranges would be helpful?


Excuse me but the code above is almost exactly what I have in my
command handling loop in the IDE.

I have classified the commands in ranges, 1000-2000 IDE,
2000-3000 Debugger, 5000-6000 Analysis, and some others.

At the same time I have special commands thatshould be treated
immediately and not in a special function, like exit, close file
and some others.
 
B

Ben Pfaff

Bartc said:
OK, let's try:

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

C99 imposes a limit of 1023 case values in a switch statement, so
that switch statement would require at least one more extension
beyond case ranges.
 
L

lawrence.jones

Richard Tobin said:
It does seem rather contrived, but I can imagine something similar
for the handling of error codes:

switch(status)
{
case 100..199:
handle_informational(); break;
case 200..299:
handle_success(); break;
case 300..399:
handle_redirection(); break;
case 400..499:
handle_client_error(); break;
case 500..599:
handle_server_error(); break;
}

switch(status/100)
{
case 1:
handle_informational(); break;
case 2:
handle_success(); break;
case 3:
handle_redirection(); break;
case 4:
handle_client_error(); break;
case 5:
handle_server_error(); break;
}

-Larry Jones

I don't think that question was very hypothetical at all. -- Calvin
 
B

Bartc

Ben Pfaff said:
C99 imposes a limit of 1023 case values in a switch statement, so
that switch statement would require at least one more extension
beyond case ranges.

That seems overly restrictive. I guess the rule is there to limit the number
of /individual/ case-expressions so that the compiler can cope. But my
example above has only 3.. or maybe 6. So yes the rule would need modifying
a little.
 
B

Bartc

Eric Sosman said:
Did you find this (or its equivalent) in an actual
program, or did you simply make it up? My point is not
that a ranged-case switch cannot be imagined, but that
its actual utility is in doubt. Can you find an example
of a real program -- or even a realistic programming
situation -- where case ranges would be helpful?

This is a piece of code made-up from bits and pieces I remember. Examples
with ranges are not difficult to think up, even useful ones.

Ranges are useful; some languages even have a special datatype for them.

And especially useful for characters where even if ASCII can't be assumed a
simple function (Asc(), a nop on my machine) can ensure codes are
well-behaved enough to use in ranges.

And implementing ranges in a switch I think is fairly trivial for a
compiler. In fact, there are no downsides I can think of. The only argument
is what symbol to use in between. So there's little cost.

However I think my point of view may be a bit different, I see switch as a
form of if-elseif-else statement.
A programmer who assumes ASCII nowadays is begging
for a tongue-lashing from Anders Ångström, Béla Bartók,
Julius Cæsar, and everyone else through Jan Žižka.
...The 'A' ... 'Z' range was useful once upon a time,

See my comment above. Map to a consecutive set and make life a bit simpler.
 
B

Ben Pfaff

It does seem rather contrived, but I can imagine something similar
for the handling of error codes:

switch(status)
{
case 100..199:
handle_informational(); break;
case 200..299:
handle_success(); break;
case 300..399:
handle_redirection(); break;
case 400..499:
handle_client_error(); break;
case 500..599:
handle_server_error(); break;
}

You could just switch on status / 100.
 
R

Richard Tobin

switch(status)
{
case 100..199:
handle_informational(); break;
[...]

You could just switch on status / 100.[/QUOTE]

I'm not recommending this style, just trying to give a plausible
use of it.

-- Richard
 
C

CBFalconer

Harald said:
Ranges are not forbidden in case statements in Pascal. See ISO10206.
Extended Pascal is also standardised.

That's extended Pascal, not Pascal. That's something like
confusing C++ and C (but not as bad). :)
 
C

CBFalconer

Eric said:
Bartc wrote:
.... snip ...

Did you find this (or its equivalent) in an actual
program, or did you simply make it up? My point is not
that a ranged-case switch cannot be imagined, but that
its actual utility is in doubt. Can you find an example
of a real program -- or even a realistic programming
situation -- where case ranges would be helpful?

A more reasonable, and legal, coding would be:

if ((cmdcode < 1000) || (cmdcode > 2999)) misccmds();
else if (cmdcode < 2000) filecmds();
else if (cmdcode < 2500) editcmds();
else viewcmds();

which I consider readable and legitimate.
 
H

Harald van Dijk

That's extended Pascal, not Pascal. That's something like confusing C++
and C (but not as bad). :)

Considering the support for it by both implementors and users, it's
closer to C99 than C++. :)
 
F

Flash Gordon

CBFalconer wrote, On 30/03/08 05:40:
A more reasonable, and legal, coding would be:

if ((cmdcode < 1000) || (cmdcode > 2999)) misccmds();
else if (cmdcode < 2000) filecmds();
else if (cmdcode < 2500) editcmds();
else viewcmds();

which I consider readable and legitimate.

Personally I find the if chain version to be less readable, less
maintainable and more error prone. It's what I do in C because it is the
only mechanism C provides, but that does not make it the best way it
could be done.
 
B

Bartc

CBFalconer said:
A more reasonable, and legal, coding would be:

if ((cmdcode < 1000) || (cmdcode > 2999)) misccmds();
else if (cmdcode < 2000) filecmds();
else if (cmdcode < 2500) editcmds();
else viewcmds();

which I consider readable and legitimate.

The code below is virtually identical to my fragment above and compiles and
runs with gcc.

So while not standard is usable on a popular C compiler.

Readability is a manner of opinion; but looking at the single line:

{case 1000..1999: filecmds(); break

I can see at a glance that all the file commands are 1xxx. Looking at:

else if (cmdcode < 2000) filecmds();

I can't. And is bit more errorprone (eg. cmdcode <= 2000 is likely).

Shame about the 'break' though. But using '#define endcase break' might
help.


#include<stdio.h>

void filecmds(int cmd) {printf("File command %d\n",cmd);}
void editcmds(int cmd) {printf("Edit command %d\n",cmd);}
void viewcmds(int cmd) {printf("View command %d\n",cmd);}
void misccmds(int cmd) {printf("Misc command %d\n",cmd);}

int main(void)
{int cmdcode,i;

for(i=0; i<100;++i) {
cmdcode=rand() & 4095;

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

CBFalconer

Bartc said:
.... snip ...


The code below is virtually identical to my fragment above and
compiles and runs with gcc.
.... snip ...

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

It is still not acceptable to standard C. In addition, if you
examine the generated code, you may find that is has been converted
to my code in the first place, or that it is generating a 2000
entry transfer table (may depend on optimization), which is not
exactly optimum code. It doesn't hurt to have a rough idea of what
the compiler generates.
 
C

Chris Dollin

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

Chuck, that's a completely missing-the-point answer; we /know/ that
`f()` isn't a CIE.

You've been doing this sort of thing a /lot/ recently. I don't
know why, so my proposed solutions -- re-read before posting,
cut back on threads, coffee control, loud prog rock during commute --
may not work for you.
 
R

Richard Bos

Ben Pfaff said:
You could just switch on status / 100.

switch(status) {
case 100..149:
handle_informational(); break;
case 200..299:
handle_success(); break;
case 300..317:
handle_redirection(); break;
case 400..448:
handle_client_error(); break;
case 500..572:
handle_server_error(); break;
default:
handle_protocol_failure(); break;
}

Also, for clarity, use #defined constants called STAT_INFO_START and
STAT_INFO_END, and similar for the other categories.

Richard
 

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,774
Messages
2,569,596
Members
45,135
Latest member
VeronaShap
Top