🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #357

Re: case()

#357
From: Perry The Cynic
Date: Fri, 17 Aug 1990 18:24
85 lines
4540 bytes
In article <9907@rice-chex.ai.mit.edu> rpk@rice-chex.ai.mit.edu (Robert Krajewski) writes:
> In article <962@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
> >I disagree.  A series of 'if' statements implies a sequence of tests
> >to be performed.  A 'switch' implies a multi-way branch in which any
> >of the possible case values are equally likely to occur.  This can
> >be easily optimized by a compiler.  Although the standard does not 
> >mandate it, a switch statement is expected, in most cases, to be 
> >implemented as a quick indirect-jump table.
>
> Let the compiler decide that, then. switch should just specify
> semantics.

Exactly. A resonable compiler will compile a switch with two or three cases
as an if/then/else sequence, internally. Often compilers also break up
switches with large gaps between tag values.

> >It is not unusual to have switches with over 100 cases which would
> >not perform acceptably as a series of 'if' statements.  Syntactical
> >sugar indeed!
> 
> Well, there is one other benefit to switch: the switched thing is
> an expression, it is evaluated only once, right ?  So you get a
> temporary for free if you need it.
> 
> I would like to see switch be extended at least to cover data types
> for which == holds.  It's unfortunate that case tags have to be constants,
> but I can live with that.

The problem here is that the compiler has no guarantee that a user-defined
operator== provides the nice mathematical properties of true equality. For
all the compiler knows, for a user-defined type T, "a==b && b==c" does not
necessarily imply "a==c"; in fact it doesn't even guarantee "b==a". Yes, it's
bad coding to violate these expected properties, but a compiler can't rely
on "good form", only on the language standard.

Thus, you'd have to carefully define whether
	switch (x) { case a: mumble(); }
means
	if (x==a) mumble();
or
	if (a==x) mumble();
Neither interpretation strikes me as inherently more obvious. You don't really
want to add this kind of confusion to the language.


		About non-constant case tags:

The main problem with allowing non-constant case tags is precisely that the
"switch" statement is intended as a "simultaneous choice" operation, not 
a sequential scan. Consider this example:

	switch (expr) {
	case foo(): mumble(); break;
	case bar(): tumble(); break;
	}

How are foo() and bar() evaluated? Both, before a choice is made? In what
order? If you *require* both foo() and bar() to be always evaluated, the
compiler can't short-circuit things if it finds an early match, so the result
would never be more efficient than an if-cascade. And what happens if foo()
and bar() evaluate to the same value? Execute mumble() or tumble(), or both()
(in what order :-)? This isn't a can of worms, it's a whole truck load.
If you want a good laugh, try to interprete this:

	switch (n) {
	case n++: n--; mad(); break;
	case n++: n--; ness(); break;
	}

Just to beat the dead horse into pulp, imagine that expr (and foo and bar)
above are of a user-defined type with an operator== defined. Now the compiler
is completely clue-less. It is possible that "expr==foo() && expr==bar()"
but "foo() != bar()". To give well-defined semantics to this construct, we
would have to rigidly define one particular order of evaluation for things.
And that would indeed reduce this new construct to purely syntactic sugar on
top of an if/then/else cascade.
  -- perry

P.S.:	If your main concern is the visual ugliness and confusion of long
	if-cascades, you can use the preprocessor to make your own syntax.
	I'm not sure that I would recomment that, though.
-- 
--------------------------------------------------------------------------
Perry The Cynic (Peter Kiehtreiber)		       perry@arkon.key.com
** What good signature isn't taken yet? **  {amdahl,sgi,pacbell}!key!perry
Technical Details
Message-ID: <2052@key.COM>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!sdd.hp.com!decwrl!nsc!amdahl!key!perry
References: <26842@pasteur.Berkeley.EDU> <26857@pasteur.Berkeley.EDU> <56515@microsoft.UUCP> <962@bbxsda.UUCP> <9907@rice-chex.ai.mit.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!sdd.hp.com!decwrl!nsc!amdahl!key!perry
From: perry@key.COM (Perry The Cynic)
Newsgroups: comp.std.c++
Subject: Re: case()
Summary: Why non-constant case tags are a bad idea.
Keywords: case statement
Message-ID: <2052@key.COM>
Date: 17 Aug 90 18:24:13 GMT
References: <26842@pasteur.Berkeley.EDU> <26857@pasteur.Berkeley.EDU> <56515@microsoft.UUCP> <962@bbxsda.UUCP> <9907@rice-chex.ai.mit.edu>
Reply-To: perry@arkon.key.COM (Perry The Cynic)
Organization: Key Computer Laboratories, Fremont
Lines: 85