[comp.std.c] Proposed Enhancement to select/case

burley@world.std.com (James C Burley) (08/30/90)

After seeing some of the discussions about what can't (or shouldn't) be added
to C/C++ select/case construct capabilities, I'd like to post my thoughts on
something that might actually be useful and should be easy to implement.

First off, this proposal applies to both C++ and C.  I don't suggest adding
any new types; run-time expressions on cases; class types on selects/cases; or
anything like that.  Plenty of people have provided excellent explanations of
why those features would not be desirable.

But how about this: allow ranges (and, perhaps, lists) on case statements.
I'll pick a syntax for now -- using brackets, though perhaps someone has a
better idea.  Here's an example:

select(foo)  // Nothing new here.
  {
  case ALPHA:  // Nothing new here.
    ...

  case [BETA:GAMMA]:  // Matches any value for foo where BETA<=foo<=GAMMA.
    ...

  case [:MINIMUM,MAXIMUM:]:  // Matches foo<=MINIMUM or foo>=MAXIMUM.
    ...

  case [EPSILON,OMEGA]:  // like "case EPSILON: case OMEGA:".
    ...

  case [DELTA:PI,TAU]:  // like "case [DELTA:PI]: case TAU:".
    ...

  }

To summarize, a case statement may have a comma-separated list of
case-range-exprs (at least one item in the list) within brackets instead of
the usual integral constant expression.  Each case-range-expr is either an
integral constant expression (called "int-expr" subsequently), "int-expr:",
":int-expr", or "int-expr:int-expr".

Within a switch construct, only one case-range-expr with the form ":int-expr"
is permitted, and only one with the form "int-expr:" is permitted.  If two
case-range-exprs exist, one with the each of these forms, "default" is not
permitted (or, it could be interpreted as a null range, described below, if
people want).

If a given case-range-expr effectively specifies a null range, it is considered
a null case range.  Null case ranges are permitted.  A null range occurs if
the int-expr in ":int-expr" is less than the minimum value representable
by the type of the expression in the select statement; if the int-expr in
"int-expr:" is greater than the maximum value representable; or, for a range
of the form "lowest:highest", lowest>highest, lowest>maximum-value, or
highest<minimum-value.

Enough technotrivia: the only really useful new features are the ":i", "i:"
range forms to designate things "default" currently cannot, and the "i:j"
form to designate gaps in constants whose actual values are defined by
"someone else" (some #include file).  The ability to use commas to make
lists is purely for convenience.

I believe nothing about this proposal is at all difficult to implement in
terms of parsing or generating code.  Compilers generating tables would have
to specially handle the open-ended ranges (":i" and "i:"), but my guess is
their implementations of default with such tables are already very close.

Finally, we'd all be able to write (yeah, here's the good part):

switch(c)
  {
  case ['A':'Z','a':'z']:
    // letter

  case ['0':'9']:
    // digit

  case [:' '-1,'~'+1:]:
    // unprintable character

  }

This is easier than listing everything using lots of "case" statements, and
(usually) faster than using <ctype.h> functions (macros).  I'm not going to
say it's any more portable, however; in fact it is less portable than using
<ctype.h> or just listing all the letters (and digits?) individually.  It's
a "hacker's example" of the utility of case ranges; a more realistic example
is hinted at in the first sample in this posting (where the source code
containing the select is not under the same control as that defining the
constants in the case statements).

A thought: although I still shiver at the idea of allowing float or
double types on a select, the availability of ranges somewhat lessens the
arguments against it: the language could disallow any case specification
(other than, perhaps, the constant 0.) was not a range.  However, once one
has floats, one next wants ways to say "foo<0.", "foo==0.", "foo>0.",
for example, somehow extending the syntax to specify "<" or ">" comparisons
instead of "<=" or ">=".  And I think that suggests floats are going too far.

Anyway, the basic idea of case ranges (and lists of cases) comes from Fortran
90, as many of you already know.  Please don't assume that it therefore is a
bad idea!

Does anyone know any good reasons NOT to implement some or all of these
features in today's C++ and C compilers, with an eye towards codifying them
in the next ANSI standards for these languages?  I wouldn't suggest putting
them into the standards until people had had a couple of years to try them
out in real code...if they're not useful, let's not add the extra baggage; at
least that's my philosophy as a C programmer!

James Craig Burley, Software Craftsperson    burley@world.std.com

henry@zoo.toronto.edu (Henry Spencer) (08/30/90)

In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
>... how about this: allow ranges (and, perhaps, lists) on case statements.

Such a feature appeared in one draft of ANSI C, and disappeared in the
next.  I believe the reason was the usual:  there was no implementation
experience with it, and it was a minor convenience rather than a solution
to a serious problem.
-- 
TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology
OSI: handling yesterday's loads someday|  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/31/90)

In article <1990Aug30.164610.3519@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
>>... how about this: allow ranges (and, perhaps, lists) on case statements.
>Such a feature appeared in one draft of ANSI C, and disappeared in the
>next.  I believe the reason was the usual:  there was no implementation
>experience with it, and it was a minor convenience rather than a solution
>to a serious problem.

That's why it vanished.  Although it was before my time, I heard that
the reason it appeared was that the preceding X3J11 meeting was held in
Europe and was overrun with Pascal freaks.  The Pascalisms were removed
at the next meeting, where C freaks dominated.

diamond@tkou02.enet.dec.com (diamond@tkovoa) (08/31/90)

In article <13714@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
>In article <1990Aug30.164610.3519@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>>In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:

>>>... how about this: allow ranges (and, perhaps, lists) on case statements.

>>Such a feature appeared in one draft of ANSI C, and disappeared in the

>the reason it appeared was that the preceding X3J11 meeting was held in
>Europe and was overrun with Pascal freaks.  The Pascalisms were removed
>at the next meeting, where C freaks dominated.

The Pascalisms were not removed.  Prototypes, pointers to array types,
and the requirement to diagnose violations of syntax and constraints
made it into the final edition.  There are probably others too.

-- 
Norman Diamond, Nihon DEC       diamond@tkou02.enet.dec.com
We steer like a sports car:  I use opinions; the company uses the rack.

meissner@osf.org (Michael Meissner) (08/31/90)

In article <13714@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn)
writes:

| In article <1990Aug30.164610.3519@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
| >In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
| >>... how about this: allow ranges (and, perhaps, lists) on case statements.
| >Such a feature appeared in one draft of ANSI C, and disappeared in the
| >next.  I believe the reason was the usual:  there was no implementation
| >experience with it, and it was a minor convenience rather than a solution
| >to a serious problem.
| 
| That's why it vanished.  Although it was before my time, I heard that
| the reason it appeared was that the preceding X3J11 meeting was held in
| Europe and was overrun with Pascal freaks.  The Pascalisms were removed
| at the next meeting, where C freaks dominated.

Doug, you heard wrong.

It was one of the Boston based meetings that it got added in.  I seem
to remember that it was Joe Mueller then of Tektronix who lead the
fight to put it in.  Larry Roseler (original redactor of the document)
then of AT&T lead the fight to remove it in the next meeting, because
it was syntactic sugar that was needed.  In particular, one of the
problems that kept being mentioned was 'a'..'z', since on EBCDIC there
are 10 or so characters between 'i' and 'j' (and likewise between 'I'
and 'J').  I think the year was 1985, but it could have been earlier
or later -- definately before 1987 when I was transfered to North
Carolina.  The vote both times were fairly close (this was when a 50%
+ 1 person majority was needed to change the base document), so it
wasn't a case of being overrun with Pascal freaks.
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Do apple growers tell their kids money doesn't grow on bushes?

mikeb@ee.ubc.ca (Mike Bolotski) (09/01/90)

In article <1990Aug30.164610.3519@zoo.toronto.edu>, henry@zoo.toronto.edu (Henry Spencer) writes:
> In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
> >... how about this: allow ranges (and, perhaps, lists) on case statements.
> 
> Such a feature appeared in one draft of ANSI C, and disappeared in the
> next.  I believe the reason was the usual:  there was no implementation
> experience with it, and it was a minor convenience rather than a solution
> to a serious problem.

From the G++ info file:

Switch Ranges
=============

A GNU C++ extension to the switch statement permits range specification
for case values.  For example, below is a concise way to print out
a function parameter's "character class:"

     print_char_class (char c) 
     {
       switch (c)
         {
         case 'a'..'z': printf ("lower case\n"); break;
         case 'A'..'Z': printf ("upper case\n"); break;
         case '0'..'9': printf ("digit\n"); break;
         default:       printf ("other\n");
         }
     }

Duplicate, overlapping case values and empty ranges are detected and
rejected by the compiler.

--
Mike Bolotski          VLSI Laboratory, Department of Electrical Engineering
mikeb@salmon.ee.ubc.ca University of British Columbia, Vancouver, Canada 

burley@world.std.com (James C Burley) (09/01/90)

In article <1990Aug31.134248@ee.ubc.ca> mikeb@ee.ubc.ca (Mike Bolotski) writes:

   In article <1990Aug30.164610.3519@zoo.toronto.edu>, henry@zoo.toronto.edu (Henry Spencer) writes:
   > In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
   > >... how about this: allow ranges (and, perhaps, lists) on case statements.
   > 
   > Such a feature appeared in one draft of ANSI C, and disappeared in the
   > next.  I believe the reason was the usual:  there was no implementation
   > experience with it, and it was a minor convenience rather than a solution
   > to a serious problem.

   From the G++ info file:

   Switch Ranges
   =============

   A GNU C++ extension to the switch statement permits range specification
   for case values.  For example, below is a concise way to print out
   a function parameter's "character class:"

	print_char_class (char c) 
	{
	  switch (c)
	    {
	    case 'a'..'z': printf ("lower case\n"); break;
	    case 'A'..'Z': printf ("upper case\n"); break;
	    case '0'..'9': printf ("digit\n"); break;
	    default:       printf ("other\n");
	    }
	}

   Duplicate, overlapping case values and empty ranges are detected and
   rejected by the compiler.

   --
   Mike Bolotski          VLSI Laboratory, Department of Electrical Engineering
   mikeb@salmon.ee.ubc.ca University of British Columbia, Vancouver, Canada 

Ok, great, then we can all forget about my original recommendation.  Right
after the posting I began thinking that the [x:y]: syntax I proposed was
obnoxious, and though it isn't really ambiguous (because "?" isn't by itself
an operator), use of the colon in this new way might bother some people (though
of course it already is used in this way -- consider "case x?y:z:", where x,
y, and z are all constants).  I thought maybe "..." or ".." would be a better
separator.

Sure enough, somebody emailed me with the very same comments (not a user of
GNU CC), and we entered into a discussion of various syntax possibilities.
(One issue was that the list feature, as in "case 1,2,3:", would make a second
case I know of where the comma operator is "turned off" to support a different
use of comma and thus requires an expression using the comma operator in that
context to be placed in parens -- the first case is "foo(1,2,3)", a function
invocation.)

So I was considering reposting my proposal with this modified syntax, but
here somebody points out that GNU CC already has it!!  This is all that is
needed.  As I said (at the end of my original posting), I expect this feature
would be added to the C/C++ standard only if existing practice proved it
useful.  GNU CC establishes existing practice: useful is established (later)
by comments received by the standards committee, or perhaps seeing more vendors
of other C compilers add the same features to be GNU compatible (due presumably
to demand by customers/marketing).

I still have two questions: does "case ..MINIMUM:" match any value of the
expression less than or equal to MINIMUM, and "case MAXIMUM..:" accordingly
match expr>=MAXIMUM and, if not, would these be useful features?

Also, why didn't anybody point out how stupid it was for me to say that if
both minimum and maximum cases were specified (i.e. "case ..MINIMUM:" and
"case MAXIMUM..:" in a switch), "default" could not be specified!  (Sigh, I
forgot about the need to catch "hole" values not specified by "case"
statements for values between MINIMUM and MAXIMUM....)  In any case, thanks
for not jumping all over me about that.

Someday I've got to get a UNIX box and start using GNU software.

James Craig Burley, Software Craftsperson    burley@world.std.com

rfg@NCD.COM (Ron Guilmette) (09/02/90)

In article <BURLEY.90Aug30030645@world.std.com> burley@world.std.com (James C Burley) writes:
<
<...But how about this: allow ranges (and, perhaps, lists) on case statements.

There are two separate questions here.  One concerns case ranges, and the
other concerns lists.  I perfer to talk about each separately.

Regarding case ranges, my personal feeling is that this is a good and useful
feature and that it ought to make its way into the final standard for C++.
It is my understanding that this feature was proposed during the ANSI C
deliberations, but that it was rejected by X3J11 (for reasons that I'm not
clear on).  Perhaps someone who served on X3J11 could give us a quick
summary about what happened to case ranges in X3J11.

Anyway, ANSI C standard or no, some C compiler vendors do offer this feature.
The only one I'm sure offers it is MetaWare.

In the C++ would, g++ offers case ranges.  This should prevent X3J16 members
from rejecting the idea outright because of a lack of prior art.

By the way, I believe that both MetaWare C and g++ implement case ranges via
a syntax like:

	case LOW..HIGH:

Regarding "case lists", it seems clear that a simple syntax, i.e.:

	case FOO,BAR:

won't work because the separator comma could be parsed as the normal comma
operator, which would mess up everything.  James proposes:

	case [FOO,BAR]:

which is more verbose than the simple syntax but which still saves a bit of
typing relative to:

	case FOO:
	case BAR:

The only problem is that the values used to designate cases should (if reason
prevails) still be allowed to be formed from "static constant expressions"
and thus, the problem of the comma being parsed as a comma operator still
plagues this syntax also.

Anyway, it looks like developing a special syntax for "case lists" may be
more trouble than it is worth.

<I believe nothing about this proposal is at all difficult to implement in
<terms of parsing or generating code.

Correct.

<Anyway, the basic idea of case ranges (and lists of cases) comes from Fortran
<90, as many of you already know.

I think not.  I'm pretty sure that case ranges appeared in Pascal long
before anybody in FORTRAN land ever though of the idea.

<Does anyone know any good reasons NOT to implement some or all of these
<features in today's C++ and C compilers, with an eye towards codifying them
<in the next ANSI standards for these languages?

Apparently, Michael Tiemann could not think of any serious problem with
case ranges, so he went forth and implemented them.

<I wouldn't suggest putting
<them into the standards until people had had a couple of years to try them
<out in real code...

Right.  Given that this feature has already been in g++ for some time,
you may consider it "prior art".

-- 

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.

henry@zoo.toronto.edu (Henry Spencer) (09/02/90)

In article <1990Aug31.134248@ee.ubc.ca> mikeb@salmon.ee.ubc.ca writes:
>         case 'A'..'Z': printf ("upper case\n"); break;

Heh heh.  What does this do on an EBCDIC machine?  Not what you think!
POSIX 1003.2, which unlike the GNoids has seriously *thought* about the
problem, eventually decided that use of such ranges was inherently
unportable.  It also has a problem in that it is Anglocentric:  the
intent is presumably to pick up all uppercase alphabetics, but that
is *not* necessarily A through Z.  1003.2 has made some minor extensions
to regular-expression syntax, for example, so you can really say "match
any uppercase alphabetic", rather than saying "match A through Z" and
hoping that's right.
-- 
TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology
OSI: handling yesterday's loads someday|  henry@zoo.toronto.edu   utzoo!henry

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/02/90)

In article <1941@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
>The Pascalisms were not removed.  Prototypes, pointers to array types,
>and the requirement to diagnose violations of syntax and constraints
>made it into the final edition.  There are probably others too.

I wouldn't call those Pascalisms.  Stricter typing as such might be
considered inspired by the Pascal school, but prototypes were I think
inspired by C++ existing practice (modified to grandfather in the old
C usage of empty parameter lists in declarations).  For the most part
the stricter typing rules, diagnostic requirements, etc. naturally
evolved as a side effect of trying to devise an enforceable standard.

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/02/90)

In article <MEISSNER.90Aug31102441@osf.osf.org> meissner@osf.org (Michael Meissner) writes:
>It was one of the Boston based meetings that it got added in.

Ah, academic freaks not Pascal freaks.  :-)  Thanks for the corrected history.

>... one of the problems that kept being mentioned was 'a'..'z'

That's not a problem, is it?  The only sane meaning would be the numbers from
'a' through 'z', however many there may be  (These are numbers, not characters!)
That fact that that particular code would probably not correctly achieve the
programmer's intention is the programmer's problem, not the language's.

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/02/90)

In article <1990Aug31.134248@ee.ubc.ca> mikeb@salmon.ee.ubc.ca writes:
>From the G++ info file:
>For example, below is a concise way to print out a function parameter's
>"character class:"
[example deleted]

What the G++ info file doesn't tell you is that that example is a mistake!

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/02/90)

In article <1420@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>Perhaps someone who served on X3J11 could give us a quick
>summary about what happened to case ranges in X3J11.

What do you mean, what happened to them?  They were an unnecessary
invention and so were omitted from the standard, just like thousands
of other such inventions.  This is explained in the cover text to
any of the official X3J11 responses to public review comments.

burley@world.std.com (James C Burley) (09/04/90)

In article <1990Sep1.224336.22846@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:

   In article <1990Aug31.134248@ee.ubc.ca> mikeb@salmon.ee.ubc.ca writes:
   >         case 'A'..'Z': printf ("upper case\n"); break;

   Heh heh.  What does this do on an EBCDIC machine?  Not what you think!

I think if you look at my original posting, you'll see a kind of backhand
mention of this issue (I said something about it not being any more portable
than a switch with a bunch of cases, in fact maybe less portable).

Anyway, in case you missed it, the issue has been "decided".  GNU C already
implements such a construct; and it is a widely used compiler.  When the
next standard begins "happening", it will be up to the committee (with all
our input) to determine whether ranges (and lists) are useful and simple enough
to add, compared to the costs of any possible lack of portability being
introduced.

Meanwhile, I personally would not use the range feature for the above case
except in some kind of quick&dirty throwaway program.  I'm looking to it
more as an elegant way to deal with natural (i.e. portable) ranges that occur
in applications, and cases where the switch (not select, as I'm wont to say
as a Fortran-90 victim) statement and it's case statements are being written
by someone who does not (or should not/doesn't want to) know the values of
#define constants for the cases (presumably kept in an #include file) but
still wants to handle ranges.  Nothing wrong with that, I wouldn't think.

James Craig Burley, Software Craftsperson    burley@world.std.com

hp@vmars.tuwien.ac.at (Peter Holzer) (09/05/90)

burley@world.std.com (James C Burley) writes:
>Anyway, in case you missed it, the issue has been "decided".  GNU C already
>implements such a construct; and it is a widely used compiler.  When the
>next standard begins "happening", it will be up to the committee (with all
>our input) to determine whether ranges (and lists) are useful and simple enough
>to add, compared to the costs of any possible lack of portability being
>introduced.

No. GCC does not implement that construct (at least version 1.37.1
does not, and I think this is about the newest version (although I heard
about 1.37.92 -- what's that?)), but G++ does.
And the fact that ONE _C++_ compiler implements a feature is not likely to
count as prior art of_C_ .

>Meanwhile, I personally would not use the range feature for the above case
>except in some kind of quick&dirty throwaway program.  I'm looking to it
>more as an elegant way to deal with natural (i.e. portable) ranges that occur
>in applications, and cases where the switch (not select, as I'm wont to say
>as a Fortran-90 victim) statement and it's case statements are being written
>by someone who does not (or should not/doesn't want to) know the values of
>#define constants for the cases (presumably kept in an #include file) but
>still wants to handle ranges.  Nothing wrong with that, I wouldn't think.

Agreed. Ranges do have their advantages, and although I do not need
them (I can use if () else if () ..., but then I do not need case (),
either), I would not mind having them in a C compiler (GNU people, are
you listening ?)
--
|    _	| Peter J. Holzer			| Think of it	|
| |_|_)	| Technische Universitaet Wien		| as evolution	|
| | |	| hp@vmars.tuwien.ac.at			| in action!	|
| __/  	| ...!uunet!mcsun!tuvie!vmars!hp	|     Tony Rand	|

karl@haddock.ima.isc.com (Karl Heuer) (09/05/90)

In article <13719@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes:
>In article <MEISSNER.90Aug31102441@osf.osf.org> meissner@osf.org (Michael Meissner) writes:
>>... one of the problems that kept being mentioned was 'a'..'z'
>
>That's not a problem, is it?  The only sane meaning would be the numbers from
>'a' through 'z', however many there may be...  That fact that that particular
>code would probably not correctly achieve the programmer's intention is the
>programmer's problem, not the language's.

Well put.

There are two reasons why 'a'..'z' might not be the right answer: (a) the
alphabet isn't contiguous (e.g. EBCDIC) or (b) the locale doesn't use English.

Objection (a) is valid, but may plausibly be countered with "I don't care
about oddball machines like that".  For many programs, it simply isn't worth
the effort to make them strictly conforming%.  Besides which, preprocessor
conditionals may have already established the alphabet, thus making the use
portable:
	#if _X_ASCII
	#define LOWER 'a'..'z'
	#endif
	#if _X_EBCDIC /* need case lists as well as ranges */
	#define LOWER 'a'..'i','j'..'r','s'..'z'
	#endif
	... switch (ch) ... case LOWER: ...

Objection (b) doesn't necessarily apply.  If the program is processing natural
language text, then islower() is certainly better&.  But I think it's more
likely (in the world of existing programs commonly found on Unix systems) that
it's processing some flavor of computer language: for example, ed(1) has
exactly 26 mark registers in any locale, doesn't it?

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint
________
% Lots of people don't bother to cast pointers before handing them to a
  prototypeless free(); this fails on word-addressible architectures, which is
  probably a more likely situation than non-ASCII.  One's complement is my
  personal bugaboo; I have no idea how much of my code it would break.
& Even this is probably the wrong answer: islower() tests the *union* of the
  English alphabet and the locale's alphabet; islower('w') tests true even in
  a country where 'w' is not a letter.

karl@haddock.ima.isc.com (Karl Heuer) (09/05/90)

In article <1420@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes:
>Regarding "case lists", it seems clear that a simple syntax, i.e.:
>	case FOO,BAR:
>won't work because the separator comma could be parsed as the normal comma
>operator, which would mess up everything.

It would mean that, in the unlikely event that the user *wants* a comma
operator in a case label, he has to parenthesize the expression.  No different
from the existing situation with function arguments or initializer lists,
except that it's a minor incompatibility with the existing language.

>Right.  Given that this feature has already been in g++ for some time,
>you may consider it "prior art".

Is there any particular reason this got added to g++ but not gcc?  It would
seem to be equally useful in both.

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint

daveg@near.cs.caltech.edu (Dave Gillespie) (09/05/90)

>>>>> On 1 Sep 90 22:43:36 GMT, henry@zoo.toronto.edu (Henry Spencer) said:

> In article <1990Aug31.134248@ee.ubc.ca> mikeb@salmon.ee.ubc.ca writes:
>>         case 'A'..'Z': printf ("upper case\n"); break;

> Heh heh.  What does this do on an EBCDIC machine?  Not what you think!

Here's a solution:  In <ctype.h> define macros which expand to the
necessary case ranges and/or lists for various subsets of the target
character set:  Lowercase alpha, uppercase alpha, and digits.

A somewhat ugly but workable underlying case syntax would be, e.g.:
    case 'a'..z'; 'A'..'Z'; '_':  begin_c_identifier(); break;

One flaw with this is that isalpha() can be defined to be run-time
configurable for different national alphabets, but macros cannot.

Perhaps the "right" extension is to allow arbitrary predicates in
a case label ("case isalpha:"), but I can't think of a really nice
syntax for it, especially if you want to allow macros to be used as
the predicate.

								-- Dave
--
Dave Gillespie
  256-80 Caltech Pasadena CA USA 91125
  daveg@csvax.cs.caltech.edu, ...!cit-vax!daveg

staff@cadlab.sublink.ORG (Alex Martelli) (09/07/90)

karl@haddock.ima.isc.com (Karl Heuer) writes:

	...omitted...
>% Lots of people don't bother to cast pointers before handing them to a
>  prototypeless free(); this fails on word-addressible architectures, which is
>  probably a more likely situation than non-ASCII.  One's complement is my
>  personal bugaboo; I have no idea how much of my code it would break.

More likely?!?!  I'd bet there's twice as many IBM 370-compatibles and 
AS/400's and their ilk out there, than word-addressible machines AND
one's-complement ones *put together* (at least by some measure, say
dollar value of all programs yearly purchased for said machines,
which should be an interesting one for venal programmers...:-).

-- 
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 45, Bologna, Italia
Email: (work:) staff@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only; any time of day or night).

meissner@osf.org (Michael Meissner) (09/10/90)

In article <263@cadlab.sublink.ORG> staff@cadlab.sublink.ORG (Alex
Martelli) writes:

| >% Lots of people don't bother to cast pointers before handing them to a
| >  prototypeless free(); this fails on word-addressible architectures, which is
| >  probably a more likely situation than non-ASCII.  One's complement is my
| >  personal bugaboo; I have no idea how much of my code it would break.
| 
| More likely?!?!  I'd bet there's twice as many IBM 370-compatibles and 
| AS/400's and their ilk out there, than word-addressible machines AND
| one's-complement ones *put together* (at least by some measure, say
| dollar value of all programs yearly purchased for said machines,
| which should be an interesting one for venal programmers...:-).

Reality check time -- as far as I know, there is no C compiler for the
AS/400.  It would be an interesting experience, in a sick sort of way
from what little I've heard about the internals of this beast.  Also,
up until last year or so, C had real little penetration in the 370
market placem, except on Amdahl's version of unix.
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Do apple growers tell their kids money doesn't grow on bushes?

fouts@bozeman.bozeman.ingr.UUCP (Martin Fouts) (09/13/90)

The debate over 'a'..'z' is silly.  It is easy to define a portable
semantic which does what the programmer wants and which can be
compiled with any compiler on any machine.  By specifying the semantic
to be any member of the set of integers which maps into the character
set (here enumerate a, b, c, etc).

The problem is hinted at by Doug Gwyn in his parenthetic comment
"(These are numbers, not characters!)"  The portable solution is to
define behavior for characters, thus ending the debate.

Of course, there is no existing practice for characters as such in
either C or C++ (or many other languages) so it is probably not
appropriate for either the C or C++ standard groups to address the
problem.

The more general problem of ranges can also be discussed in the
context of enums.  The following pseudo-C code is an example of a good
use of switch statement ranges in enum land

enum Piece (Empty, King, Queen, Rook, Knight, Bishop, Pawn, Invalid);

Piece square[HIGH][DEEP];
int x, y;

switch(square[x][y]) {
  case Empty:
     handle_empty();
     break;
  case King..Pawn:
     check_attack(x,y);
     break;
  case Invalid:
     fall_apart();
  default:
     die_badly();
}

is a sample of enumeration based ranges in switch statements which are
desirable and highly portable, and for which some existing practice
(gcc) can be used as an example.

Marty
--
Martin Fouts

 UUCP:  ...!pyramid!garth!fouts (or) uunet!ingr!apd!fouts
 ARPA:  apd!fouts@ingr.com
PHONE:  (415) 852-2310            FAX:  (415) 856-9224
 MAIL:  2400 Geng Road, Palo Alto, CA, 94303

Moving to Montana;  Goin' to be a Dental Floss Tycoon.
  -  Frank Zappa

jimp@cognos.UUCP (Jim Patterson) (09/14/90)

In article <MEISSNER.90Sep9172223@osf.osf.org> meissner@osf.org (Michael Meissner) writes:
>Reality check time -- as far as I know, there is no C compiler for the
>AS/400.  It would be an interesting experience, in a sick sort of way
>from what little I've heard about the internals of this beast.

C/400 has been available for a while now, and there's also a third party
C compiler running on the AS/400. We're using C/400 for our Powerhouse (tm)
product on AS/400. 

And yes, it is an interesting experience.
-- 
Jim Patterson                              Cognos Incorporated
UUCP:uunet!mitel!sce!cognos!jimp           P.O. BOX 9707    
PHONE:(613)738-1440                        3755 Riverside Drive
                                           Ottawa, Ont  K1G 3Z4

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/15/90)

In article <740@garth.UUCP> fouts@bozeman.bozeman.ingr.UUCP (Martin Fouts) writes:
>The problem is hinted at by Doug Gwyn in his parenthetic comment
>"(These are numbers, not characters!)"  The portable solution is to
>define behavior for characters, thus ending the debate.

My point is that you switch on the value of an integer, not on a character.
There are already character classification mechanisms available, just not
using "switch".