comp.lang.c
[Top] [All Lists]

Re: case labels

Subject: Re: case labels
From: "Bartc"
Date: Fri, 28 Mar 2008 18:15:23 GMT
Newsgroups: comp.lang.c

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






<Prev in Thread] Current Thread [Next in Thread>
Privacy Policy