Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression"

Reply
Thread Tools

C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression"

 
 
lovecreatesbeauty@gmail.c0m
Guest
Posts: n/a
 
      10-24-2008
On Oct 24, 7:59 pm, "Bartc" <(E-Mail Removed)> wrote:
> "Eric Sosman" <(E-Mail Removed)> wrote in message
> > Adem wrote:
> >> The C++ Standard (ISO/IEC 14882, Second edition, 2003-10-15)
> >> says under 6.4.2(2) [see also 5.19]:
> >> case constant-expression : I propose that the case expression of
> >> the switch statement
> >> be changed from "integral constant-expression" to "integral expression".

> > switch (rand()) {
> > case rand(): puts ("What's"); break;
> > case rand(): puts ("wrong"); break;
> > case rand(): puts ("with"); break;
> > case rand(): puts ("this"); break;
> > case rand(): puts ("picture?"); break;
> > }

> What's wrong with it that you're just injecting garbage. You can use the
> same rand() trick with any statement:
>
> for (i=rand(); i<=rand(); i=rand())...


The statements following each case lable in a switch are intended to
be diffrent, while the body of for statement is the same for each
loop. Eric's trick illustrates that how bad an idean could that
proposal be.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      10-24-2008
"(E-Mail Removed)0m" <(E-Mail Removed)> writes:
> On Oct 24, 7:59 pm, "Bartc" <(E-Mail Removed)> wrote:
>> "Eric Sosman" <(E-Mail Removed)> wrote in message
>> > Adem wrote:
>> >> The C++ Standard (ISO/IEC 14882, Second edition, 2003-10-15)
>> >> says under 6.4.2(2) [see also 5.19]:
>> >> case constant-expression : I propose that the case expression of
>> >> the switch statement
>> >> be changed from "integral constant-expression" to "integral expression".
>> > switch (rand()) {
>> > case rand(): puts ("What's"); break;
>> > case rand(): puts ("wrong"); break;
>> > case rand(): puts ("with"); break;
>> > case rand(): puts ("this"); break;
>> > case rand(): puts ("picture?"); break;
>> > }

>> What's wrong with it that you're just injecting garbage. You can use the
>> same rand() trick with any statement:
>>
>> for (i=rand(); i<=rand(); i=rand())...

>
> The statements following each case lable in a switch are intended to
> be diffrent, while the body of for statement is the same for each
> loop. Eric's trick illustrates that how bad an idean could that
> proposal be.


The expressions (not statements) are intended (required, in fact) to
be integer constant expressions. The proposal is to change that
requirement. It's moderately obvious that the requirement that no two
of the case expressions would also have to be relaxed, since it's not
possible in general to determine at compilation time whether two
non-constant expressions have the same value.

Defining consistent semantics for a modified switch statement is not
all that difficult. Presumably existing switch statements would have
to behave as they do now. Beyond that, there are several possible
ways to define the semantics and constraints for switch statements
that are currently invalid.

Eric's example demonstrates the need to define the semantics of this
proposed new feature. I don't think it demonstrates, by itself, that
it's a bad idea. If non-constant switch expressions were allowed, it
would be possible to write perfectly sensible code using the new
feature. It would also, as Eric demonstrated, be possible to write
very silly code using the new feature -- or using any of the
language's existing features.

I do agree that the proposed feature is a bad idea, but not because of
Eric's example. I think it's a bad idea because it would have to
define new semantics for an existing construct. Currently, if you
accidentally use a non-constant case expression, the compiler will
diagnose it as an error (and probably reject your program). Under the
proposal, the code would be valid, and would likely behave in a subtly
wrong manner and/or with poor performance. Evaluating the switch
expression and branching to the right case label is typically an O(1)
operation, if the compiler is able to generate a jump table. Add a
single non-constant expression, and it becomes O(N), where N is the
number of cases.

I wouldn't object as strongly to a new feature, with a distinct
syntax, that implements the proposed functionality, but I'd still
oppose it -- not because it's an inherently bad idea, but because the
benefit is IMHO outweighed by the cost of adding a new feature to the
language. There's nothing you could do with the proposed new feature
that you can't already do fairly straightforwardly using existing
features, namely an if/else chain and, if the switch expression is
complicated or has side effects, a temporary variable.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
CBFalconer
Guest
Posts: n/a
 
      10-24-2008
anon wrote:
>

.... snip ...
>
> There is something wrong. Try to compile this example, and I hope
> you figure whats wrong with his proposal :
>
> int main()
> {
> int a = 3;
> switch( a )
> {
> case 3:
> a = 1;
> break;
> case 3:
> a = 2;
> break;
> case 3:
> a = 3;
> break;
> default:
> a = 4;
> }
> }


Your code works better if it is made legal:

int main(void) {
int a = 3;

switch( a ) {
case 3: a = 1;
break;
case 2: a = 2;
break;
case 1: a = 3;
break;
default: a = 4;
}
return 0;
}

Also, cross posting to c.l.c++ is not cool.


--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      10-24-2008

"Eric Sosman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed). ..
> Bartc wrote:
>>
>> "Eric Sosman" <(E-Mail Removed)> wrote in message
>> news:1224788466.760836@news1nwk...
>>> Adem wrote:
>>>> C/C++ language proposal: Change the 'case expression' from "integral
>>>> constant-expression" to "integral expression"


>>> switch (rand()) {
>>> case rand(): puts ("What's"); break;
>>> case rand(): puts ("wrong"); break;
>>> case rand(): puts ("with"); break;
>>> case rand(): puts ("this"); break;
>>> case rand(): puts ("picture?"); break;


>> What's wrong with it that you're just injecting garbage. You can use the
>> same rand() trick with any statement:
>>
>> for (i=rand(); i<=rand(); i=rand())...

>
> This has well-defined semantics, albeit not very useful.
> The purpose of my example wasn't to claim that it is impossible
> to invent semantics for the O.P.'s `switch', but to show that
> the proposal as it stands is not even close to adequate.
>
> Let's try another one:
>
> switch (x) {
> case f(x): puts("f"); break;
> case g(x): puts("g"); break;
> }
> ...
> int f(int x) { puts("in f"); return x & 1; }
> int g(int x) { puts("in g"); return x & 2; }
>
> What output do you desire when `x == 16'? Two lines?
> Three? Four? In what order?


When x is 16, both f() and g() return 0, which does not equal x so matches
neither case.

You're thinking in terms of the current switch semantics which likes unique
case values and can take them in any order. That's why I suggested a
different statement (or just a different keyword).

(I tried this code in a language of mine that accepts expressions for case
expressions. The output was "in f" followed by "in g".

In this language there are two distinct statements: switch-when for integer
values over a small range,expected to be implemented as a jump table (ie. C
switch); and case-when for anything else: large integers or other types.
Although I don't think I've ever used a non-const expression for a
switch/case value. Until now)

--
Bartc

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-25-2008
CBFalconer <(E-Mail Removed)> writes:
> anon wrote:
>>

> ... snip ...
>>
>> There is something wrong. Try to compile this example, and I hope
>> you figure whats wrong with his proposal :
>>
>> int main()
>> {
>> int a = 3;
>> switch( a )
>> {
>> case 3:
>> a = 1;
>> break;
>> case 3:
>> a = 2;
>> break;
>> case 3:
>> a = 3;
>> break;
>> default:
>> a = 4;
>> }
>> }

>
> Your code works better if it is made legal:
>
> int main(void) {
> int a = 3;
>
> switch( a ) {
> case 3: a = 1;
> break;
> case 2: a = 2;
> break;
> case 1: a = 3;
> break;
> default: a = 4;
> }
> return 0;
> }


Which completely and utterly misses the point.

The article that started this thread was a proposal to allow
non-constant case expressions. anon's point was that it would then
become impossible (or nearly so) to maintain the property that all
case expressions in a switch statement must have distinct values.
Your "correction" is valid C, but pointless; you might as well have
posted "int main(void) { }".

> Also, cross posting to c.l.c++ is not cool.


Perhaps, but the topic of the thread is a proposed change to both C
and C++. Arguably the comp.std.* groups would have been better, but I
think comp.std.c++ is more or less dead these days. Since switch
statements have the same syntax and semantics in C and C++, it's not
entirely unreasonable to discuss a proposed change in both.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      10-25-2008
In article <(E-Mail Removed)>,
Keith Thompson <(E-Mail Removed)> wrote:
....
>Which completely and utterly misses the point.


It's what Chuck does best. One should always play to one's strengths.

 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      10-26-2008
In article <gdqf6p$fqj$(E-Mail Removed)>, (E-Mail Removed) says...

[ ... ]

> int y, x = f();
> switch (x)
> {
> case 123 : y = g(); break;
> case g() : y = 456; break; // using new case feature, ie. func-call
> case h() : y = 789; break; // ditto
> default : y = -1; break;
> }


This has a number of ramifications that could make definition difficult.
For a few examples, how often would g() be evaluated in the switch
statement above? If both g() and h() returned the same value, which leg
would be taken?

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-27-2008
Jerry Coffin <(E-Mail Removed)> writes:
> In article <gdqf6p$fqj$(E-Mail Removed)>, (E-Mail Removed) says...
>
> [ ... ]
>
>> int y, x = f();
>> switch (x)
>> {
>> case 123 : y = g(); break;
>> case g() : y = 456; break; // using new case feature, ie. func-call
>> case h() : y = 789; break; // ditto
>> default : y = -1; break;
>> }

>
> This has a number of ramifications that could make definition difficult.
> For a few examples, how often would g() be evaluated in the switch
> statement above? If both g() and h() returned the same value, which leg
> would be taken?


The person proposing the feature did not give enough information to
answer those questions. If the proposed feature were to be added to
the language, then the semantics would have to be worked out first;
doing so shouldn't be too difficult. Once that's done, the answers to
your questions become obvious rather than indeterminate. (Possibly in
some cases the execution would be implementation-defined, or
unspecified, or even undefined, but I'd prefer a simpler definition
that avoids that.)

In my preferred semantics, the above would be exactly equivalent to:

int y, x = f();
int __tmp = x;
if (__tmp == 123) y = g();
else if (__tmp == g()) y = 456;
else if (__tmp == h()) y = 789;
else y = -1;

The number of times g() is evaluated depends on the value of x and the
value returned by g(), which you haven't specified. If both g() and
h() return the same value, and that happens to be the value of x, then
y would be set to 456.

But, as I said, I think the whole thing is a bad idea.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Matthias Buelow
Guest
Posts: n/a
 
      10-28-2008
Adem wrote:
> C/C++ language proposal:
> Change the 'case expression' from "integral constant-expression" to "integral expression"


How about:

cond {
(foo == bar): ...; break;
(!bar && (baz == boo)): ...; /* fallthru */
default: ...; break;
}

In pseudo-grammar:

cond { [<expr>|default: <stmt>*]* }
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-28-2008
Matthias Buelow <(E-Mail Removed)> writes:
> Adem wrote:
>> C/C++ language proposal:
>> Change the 'case expression' from "integral constant-expression"
>> to "integral expression"

>
> How about:
>
> cond {
> (foo == bar): ...; break;
> (!bar && (baz == boo)): ...; /* fallthru */
> default: ...; break;
> }
>
> In pseudo-grammar:
>
> cond { [<expr>|default: <stmt>*]* }


One advantage of the switch statement is that the expression only has
to be written once; it's implicitly compared to each of the case label
expressions without being re-evaluated.

Your proposed "cond" statement lacks this advantage, and differs from
an if/else chain only in the ability to fall through from one case to
the next. The latter can easily be done with a goto statement. (Yes,
gotos are ugly; so is falling through from one case to the next. And
you can always restructure the code to avoid gotos.)

As for the grammar, I think you'd want to require a keyword, probably
"case", for each expression:

cond {
case foo == bar: ... break;
case !bar && (baz == boo): ...; /* fallthrough */
default: ...; break;
}

Otherwise the compiler doesn't know until it sees the ':' whether the
expression is part of the cond statement or just an ordinary
expression statement.

And of course it would break every existing program that uses "cond"
as a keyword, but that's easily solved by using "_Cond".

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"Change your language and you change your thoughts." Suganya C Programming 0 04-29-2008 01:35 PM
A Paradise DNS address change? What change? There was no change. Tony Neville NZ Computing 7 09-22-2006 01:02 PM
A language-agnostic language Ed Java 24 03-27-2006 08:19 PM
Using a Scripting Language as Your Scripting Language DaveInSidney Python 0 05-09-2005 03:13 AM
Python is the best and most popular general purpose scripting language; the universal scripting language Ron Stephens Python 23 04-12-2004 05:32 PM



Advertisments