|
|
Eric Sosman wrote:
> Bartc wrote:
>> "Eric Sosman" <esosman@xxxxxxxxxxxxxxxxxxxx> wrote in message
>> news:r62dnXScdbSgaXHanZ2dnUVZ_j6dnZ2d@xxxxxxxxxxxxxx
>>> Bartc wrote:
>>>> There's no reason why switch expressions can't be any (identical)
>>>> type, as Keith has suggested.
>>> If you switch on a double, with double case labels,
>>> what's the matching criterion?
>> ...
>> 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 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.
>
>> 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.
>
> The O.P. in this case asked a very short question, from
> which you seem to derive a lot more information than I can.
He or she asked why general int expressions weren't allowed. Either this was
out of curiosity or an attempt was made to use them. Or, unlikely, constant
int expressions were tried on a compiler than didn't reduce them.
>
> 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?
To get unambiguous semantics it would be necessary to assume the same
behaviour as equivalent if statements:
if (i==x) printf("x\n");
elsif (i==y)...
The answer to your question should be No, unless you reorder.
One trouble spot I can see is if, with a mix of variable and constant
expressions, an implementor mixes if-semantics with a jump table. Reordering
would be necessary (all variables first), so that a variable with the same
value as a constant, will be matched first, even if it's in a later case.
Also I haven't thought about break (or the absence of it).
(With 1000 constant case expressions and one variable one, it would be
tempting to include a jump table.)
Despite all this, I can't find a single use of a variable switch-case
expression (or when-expression in that other language) in my code!
So I can understand why switch has been left alone. Nevertheless, this other
language does allow variables ints (or constant/variable other types) if
they are ever needed.
Using doubles needn't be fraught with problems either:
double x;
switch (x) {
case 0.0: puts("Exactly zero"); break;
case 1.0: puts("Exactly one"); break;
default: puts("Whatever x was, it wasn't exactly 0 or 1");
};
>> 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 <=.
>
>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?
I would use it if I know the switch-expression is an ASCII code.
>> And with char* strings, the compiler can apply some common sense and
>> use strcmp(). There are ways.
>
> ... 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 does strcmp() do if one of the parameters is NULL? If NULL is a problem
here, the compiler must use a safer version of strcmp(), and in this case I
would enhance it so that NULL and "" will match.
> What if it's just a char* that points at a char, but not at the start of a
> string?
That's a mild deficiency of C, not being able to distinguish between a
string and a pointer to one character. I would go with strcmp() still. For
anything else, cast to *void, then just pointers are compared.
> ... 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.
>
>> But no I don't fancy delving into the gcc sources!
>
> Well, if the advance isn't worth some fairly serious
> work, that may mean the need it addresses isn't too urgent.
I wasn't suggesting originally that C should be changed. Just pointing out
that variable case-expressions aren't allowed even though it would have been
comparatively straightforward (compared to some of the stuff in C++) to
allow them.
I know I wouldn't single-handedly be able to change anything in C, it would
be near impossible.
--
Bart
|
|