A
aarklon
Hi,
why general integer expressions are not allowed in case labels in
switch statements..????
why general integer expressions are not allowed in case labels in
switch statements..????
Hi,
why general integer expressions are not allowed in case labels in
switch statements..????
Because they must be compile time constants.
Could you elaborate this concept?
Ian Collins said:*Please* don't quote signatures.
The language requires case labels to be compile time constants. There
really isn't a concept to elaborate on.
Unless you want to know *why* the standard imposes this requirement.
The code generated for a switch statement is typically a static jump
table (though it doesn't have to be). The advantage of this is that
the code doesn't have to traverse through various possible values of
the controlling expression to determine where to jump; it's typically
faster than an equivalent if/else chain. The disadvantage is that the
values for all the labels have to be known at compile time so the
compiler can construct the jump table.
Having said that, there's nothing forbidding a compiler from treating
a switch statement like an if/else chain anyway (and it will probably
have to do something like that if the range of cases is very large).
Hi,
why general integer expressions are not allowed in case labels in
switch statements..????
Bartc said:There's no reason why switch expressions can't be any (identical) type, as
Keith has suggested.
If they are all constant integers, then fine generate a jump table.
Otherwise generate appropriate if-statements. This is very easy at a time
when C compilers are so super-sophisticated they can almost bake bread too.
But the people responsible for new C standards have decided to keep this
area of the language (control statements in general) at a primitive level.
So the programmer has to code his logic in a less expressive manner.
Eric Sosman said:If you switch on a double, with double case labels,
what's the matching criterion? ....
If you switch on a struct-valued expression, what's
the matching criterion? ....
If you switch on a `char*', should the matching
criterion be strcmp()?
If you've got ideas of how to handle questions of this
kind, get hold of the gcc source and implement your answers.
Then float it around to see whether people like it; if
they do, you'll have taken a big step towards getting it
into a revised Standard -- "prior art" is a lot more
convincing than "I wish."
If you switch on a struct-valued expression, what's
the matching criterion?
If you switch on a `char*', should the matching
criterion be strcmp()? Or caseInsensitiveStrcmp()? Or
allWhiteSpaceCountsAsIdenticalStrcmp()?
Bartc said: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.
Probably all the OP wants is to be have variable int cases, then an
extension of switch which simply applies the == operator would be a useful
advance.
Another simple enhancement is a range operator (maybe gcc has this?) like
case 'A'..'Z':, which in the case of doubles could translate into >= and <=.
And with char* strings, the compiler can apply some common sense and use
strcmp(). There are ways.
I've worked on a compiler for a language where something similar is possible
(although I found it easier to have two forms of switch: one with constant
int cases, and one with any simple type where =/== made sense). And it was
workable.
> But no I don't fancy delving into the gcc sources!
why general integer expressions are not allowed in case labels in
switch statements..????
user923005 said:A smart compiler would sort the labels and do a bsearch to find
the desired element. Or it could compute a perfect hash at
compile time.
Keith Thompson said:Having said that, there's nothing forbidding a compiler from treating
a switch statement like an if/else chain anyway (and it will probably
have to do something like that if the range of cases is very large).
*Please* don't quote signatures.
The language requires case labels to be compile time constants. There
really isn't a concept to elaborate on.
The real elaborate question i wanted to ask was
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?
Eric said:The question is whether the "advance" produces something
useful, and the situations I mentioned seem to me like real-
life problems the enhanced switch would have trouble with.
The O.P. in this case asked a very short question, from
which you seem to derive a lot more information than I can.
Besides, I'm still not convinced of the utility, even
if restricted to int values. Try this:
int x = 42, y = 43;
for (int i = 40; i < 50; ++i) {
switch (i) {
case x: printf("x\n"); break;
case y: printf("y\n"); break;
default: printf("?\n"); break;
}
y = 42;
}
int c1, c2;
c1 = getchar();
switch (c1) {
case EOF: printf("done!\n"); return;
case c2 = getchar():
printf("two %c's in a row\n", c1);
break;
default:
ungetc(c2); break;
}
Question: Is the "internal" getchar() executed if c1==EOF?
Yes, gcc has an extension like this. And yes, it's less
useful than one might think. For example, the case you show
does necessarily select all upper-case letters, nor does it
necessarily exclude all non-letters. What good is it?
... so the enhanced switch is limited to just one notion
of matching. True, it's probably the most "natural" notion
for strings, but it's not the only notion. Also, what do
you get if the char* you switch on (or one of the labels)
is NULL?
What if it's just a char* that points at a char, but not at the start of a
string?
... But is it worth the trouble? I'm not
sure -- and that's why I suggested doing an implementation
and finding out whether people would use the feature in
interesting ways.
Well, if the advance isn't worth some fairly serious
work, that may mean the need it addresses isn't too urgent.
Indeed, most compilers have a number of different strategies for
implementing switch statements that they choose from based on things
like the number of cases, their range, and density.
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?
Restricting case labels to integer constant expressions allows various
highly efficient implementations. For general expressions, there's no
more efficient implementation than a sequence of if ... else if ...
statements. Since you can already write the sequence of statements if
you need it, allowing you to write it as a switch as well wouldn't add
much expressive power but it would complicate the description of the
language and the implementation of the compiler somewhat. DMR decided
that the benefit wasn't worth the cost.
-Larry Jones
Nothing spoils fun like finding out it builds character. -- Calvin
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.