[net.lang.c] boolean datatype

mike@peregrine.UUCP (06/01/86)

This is not a proposal to change the ANSI standard.  This is just some
ideas some possible ways of improving C.
>Re: builtin bool type
>>I'm not sure why not.  Assuming all the implicit int/bool conversions stay,
>>I think the only problems are (a) it isn't really necessary, and (b) it adds
>>a new reserved word (breaking any programs that use "typedef int bool"!).
>
>(a) is the biggie.  Why add bool when "typedef enum { FALSE, TRUE } bool;"
>works fine?  (Relying on ANSI C's treatment of enums as real ints)
So that the built in statements can use them.
	...
	int n,get_number();

	n=7;
	if (n=get_number()) printf("got 7\n");	/* should have been ==		*/
	...
This is an example of a place where a C compiler with boolean types would catch
a mistake.
	...
	bool flag,get_yes_or_no();

	if (flag=get_yes_or_no()) printf("got yes\n");	/* no mistake		*/
	...
This is an exmaple of a place where most of the idea for finding mistaken
assignments would fail.

One possible way to put this in C would be to do the conversion from
int to bool(if the integer is not equal to zero then make it true else
make it false) and generate a warning.  This would add a new reserved
word and would break programs that used bool as an identifier.  At
some future time the warning could become an error message.

Another feature I would like to have is a range data type.  I don't
know of a good syntax for putting this in C but it would be nice to
use in programs where are know the possible values of a number but
would like the compiler to figure out an efficient sized slot to put
it in.
	...
	range hour:1..12; /* create a variable named hour that can vary from */
				/* 1 through 12								*/
	typedef range DAY:1..366;
	DAY day1,day2;

	hour+=2;
	day1=day2+100;
}
I will let other people argue about how to index an array by a range. 
-- 
Mike Wexler
Email address:(trwrb|scgvaxd)!felix!peregrine!mike
Tel Co. address: (714)855-3923
;-) Internet address: ucivax@ucbvax.BERKELY.EDU!ucivax%felix!mike@peregrine :-(

brett@wjvax.UUCP (Brett Galloway) (06/04/86)

In article <393@peregrine.UUCP> mike@peregrine.UUCP (Mike Wexler) writes:
>Another feature I would like to have is a range data type.  I don't
>know of a good syntax for putting this in C but it would be nice to
>use in programs where are know the possible values of a number but
>would like the compiler to figure out an efficient sized slot to put
>it in.
>	...
>	range hour:1..12; /* create a variable named hour that can vary from */
>	typedef range DAY:1..366;
>	DAY day1,day2;
>
>I will let other people argue about how to index an array by a range. 

I would prefer an operator that merely generated an integral type based on
a number of bits requested, not based on a desired range.  For example,
on a machine with 8-bit char, 16-bit short, 32-bit int, and 64-bit long,
bittype(8) == char; bittype(9) == short; bittype(31) == int; and so on.
Bittype() would be evaluated at the same time sizeof() is evaluted, which I
think is in the preprocessor.  The preprocessor would just substitute a type
word (char, int, etc.) for the bittype(n) operator.  Bittype() would NOT,
however, enforce range restrictions; it would just efficiently generate a type
that contains at least the given number of bits, if possible.

Another operator that would be useful in conjunction with the above and useful
elsewhere would be a constant-generation construct that provides knowledge of
the number of bits in each of the integral arithmetic types (char, short, int,
and long).  For example, bitlen(int) == 32 on a 32-bit machine;
bitlen(char) == 8 most of the time.  This would simplify generating efficient
code to simulate bitfield arrays.  For example, to generate a packed
100-element array of unsigned 1-bit fields, one could define an array

	unsigned int wordarray[(100+(bitlen(int)-1))/bitlen(int)];

and define macros to do the bitmask accesses.  In fact, the user could write
a general macro package to handle all this.  My understanding of the current
situation is that, short of a well-known #define in an #include file, the
only way to determine the bit-length of an integral type is at run-time, by
right/left-shifting a bit through an item of that type.  Run-time determination
is much less efficient, however.  It requires the overhead of the run-time
determination, plus it precludes compile-time constant evaluation.

Finally, while we're on the subject of wish-lists, I think a typeof()
operator would be VERY useful.

-------------
Brett Galloway
{pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett

mike@peregrine.UUCP (Mike Wexler) (06/10/86)

In article <705@wjvax.wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes:
>In article <393@peregrine.UUCP> mike@peregrine.UUCP (Mike Wexler) writes:
>>Another feature I would like to have is a range data type.  I don't
>
>I would prefer an operator that merely generated an integral type based on
>a number of bits requested, not based on a desired range.  For example,
>on a machine with 8-bit char, 16-bit short, 32-bit int, and 64-bit long,
>bittype(8) == char; bittype(9) == short; bittype(31) == int; and so on.
This is an interesting idea, but has many disadvantages.  You can't even
optionally turn on range checking, have the compiler check for range errors,
have the compiler do things like generate a jump table for a switch statement
knowing that the variable being switched on has a maximum value of 3, etc...

It also puts the burden on the user to figure out how many bits are needed
to store a particular number.  This could lead to either less efficient code
or nonportable code due to problems with signed/unsigned variables.  For 
instance if I say I want a range of 1 thru 7 the compiler could store this
in a signed or unsigned variable depending on which is most efficient.

If the reason for you suggestion is that run-time range checking is expensive.
This could be solved the same way it is handled on arrays, i.e. don't do it.
You can always add an option to the compiler to turn on range checking.
-- 
Mike Wexler
Email address:(trwrb|scgvaxd)!felix!peregrine!mike
Tel Co. address: (714)855-3923
;-) Internet address: ucivax@ucbvax.BERKELY.EDU!ucivax%felix!mike@peregrine :-(

keppel@pavepaws.berkeley.edu (David Keppel) (06/10/86)

In article <399@peregrine.UUCP> mike@peregrine.UUCP (Mike Wexler) writes:
>It also puts the burden on the user to figure out how many bits are needed
>to store a particular number.  This could lead to either less efficient code
>or nonportable code due to problems with signed/unsigned variables.  For 
>instance if I say I want a range of 1 thru 7 the compiler could store this
>in a signed or unsigned variable depending on which is most efficient.

    Now we have issues about whether we want an range 1..7 variable that
    is fast (on most machines an int) or small (byte or even bitfields).
    To handle this, you probably want to add keywords (yuk ;-) like
    "fast" and "small" so that you can say

	fast int range [1..7]	foobar = 5;
	small int range [1..7]	barbaz = 5;

    to get range checking when compiled with the right flag, but no speed
    penalty when compiled without, for the first case, and to get as small
    an int (most likely a byte) in the second case, even when compiled
    without the bounds-test flag.

    One problem I saw long ago in an intro class was along the lines of:

	int range [1..7]	foobar;
	:
	foobar = 1;
	while (foobar <= 7) {
	    stuff_to_do (foobar);
	    foobar += 1;
	}

    [ this is a bad example, but short ]
    The problem here is that you want to restrict 'foobar' to have usable
    values 1..7, but must declare it 1..8 (or 0..7) or else write some
    messy code.  I think that the prof. proposed that range-valued
    variables should be used very cautiously.

    :-D avid  K eppel				    ..!ucbvax!pavepaws!keppel
		"Learning by Osmosis: Gospel in, Gospel out"

rgh%inmet.uucp@BRL.Arpa (06/11/86)

Return-Path: <info-c-request@BRL.ARPA>
Redistributed: Xerox-Info-C^.x@XEROX.ARPA
Received: from BRL-AOS.ARPA by Xerox.COM ; 02 JUN 86 16:42:38 PDT
Received: from brl-smoke.arpa by AOS.BRL.ARPA id a015997; 2 Jun 86 17:28 EDT
Received: from USENET by SMOKE.BRL.ARPA id a005687; 2 Jun 86 17:01 EDT
Newsgroups: net.lang.c
Message-ID: <393@peregrine.UUCP>

This is not a proposal to change the ANSI standard.  This is just some
ideas some possible ways of improving C.
>Re: builtin bool type
>>I'm not sure why not.  Assuming all the implicit int/bool conversions stay,
>>I think the only problems are (a) it isn't really necessary, and (b) it adds
>>a new reserved word (breaking any programs that use "typedef int bool"!).
>
>(a) is the biggie.  Why add bool when "typedef enum { FALSE, TRUE } bool;"
>works fine?  (Relying on ANSI C's treatment of enums as real ints)
So that the built in statements can use them.
	...
	int n,get_number();

	n=7;
	if (n=get_number()) printf("got 7\n");	/* should have been ==		*/
	...
This is an example of a place where a C compiler with boolean types would catch
a mistake.
	...
	bool flag,get_yes_or_no();

	if (flag=get_yes_or_no()) printf("got yes\n");	/* no mistake		*/
	...
This is an exmaple of a place where most of the idea for finding mistaken
assignments would fail.

One possible way to put this in C would be to do the conversion from
int to bool(if the integer is not equal to zero then make it true else
make it false) and generate a warning.  This would add a new reserved
word and would break programs that used bool as an identifier.  At
some future time the warning could become an error message.

Another feature I would like to have is a range data type.  I don't
know of a good syntax for putting this in C but it would be nice to
use in programs where are know the possible values of a number but
would like the compiler to figure out an efficient sized slot to put
it in.
	...
	range hour:1..12; /* create a variable named hour that can vary from */
				/* 1 through 12								*/
	typedef range DAY:1..366;
	DAY day1,day2;

	hour+=2;
	day1=day2+100;
}
I will let other people argue about how to index an array by a range. 
-- 
Mike Wexler
Email address:(trwrb|scgvaxd)!felix!peregrine!mike
Tel Co. address: (714)855-3923
;-) Internet address: ucivax@ucbvax.BERKELY.EDU!ucivax%felix!mike@peregrine :-(

ludemann@ubc-cs.UUCP (Peter Ludemann) (06/12/86)

In article <399@peregrine.UUCP> mike@peregrine.UUCP (Mike Wexler) writes:
>In article <705@wjvax.wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes:
>>In article <393@peregrine.UUCP> mike@peregrine.UUCP (Mike Wexler) writes:

>>I would prefer an operator that merely generated an integral type based on
>>a number of bits requested, not based on a desired range.  For example,
>>on a machine with 8-bit char, 16-bit short, 32-bit int, and 64-bit long,
>>bittype(8) == char; bittype(9) == short; bittype(31) == int; and so on.
>
>It also puts the burden on the user to figure out how many bits are needed
>to store a particular number.  This could lead to either less efficient code
>or nonportable code due to problems with signed/unsigned variables.  

WSL (Waterloo Systems Language) has what you want.  It's basically a 
tidied up version of C.  The syntax is like Pascal, but no range 
checking is actually done.  So "i:1..10" would be C's "char i"; while 
"i:0..1000" would be C's "unsigned short int i".  

A commercial data centre evalutated WSL and probably would have used 
it except for the detail that there existed no WSL->C and C->WSL 
translators.  But the implementation looked quite good.  For more 
info, contact WatSoft at the University of Waterloo, Waterloo, 
Ontario, Canada.  (The book is available separately.)