Topic: bood and wchar_t [was: Prefix versus postfix operator override]


Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 10 Aug 1994 19:55:16 GMT
Raw View
In article <CuBtFs.6w3@borland.com> pete@genghis.interbase.borland.com
(Pete Becker) writes:

|> In article <KANZE.94Aug9175211@slsvhdt.us-es.sel.de>,
|> James Kanze US/ESC 60/3/164 #71425 <kanze@us-es.sel.de> wrote:

|> >Is there a similar guarantee for wchar_t?  E.g.: is the following
|> >guaranteed to work?

|> > wchar_t
|> > todigit( int i )
|> > {
|> >     assert( i >= 0 && i < 10 ) ;
|> >     return L'0' + i ;
|> > }

|> >If so, then I think that wchar_t has to be an integral type.

|>  Whether this works depends on the particular character encoding that
|> is being used by the program. Under Unicode, if I remember correctly, all
|> of the standard ASCII 7-bit characters are simply widened to 16 bits. In that
|> case, this transformation remains valid.

I'm not sure if that is an answer or not.  My question was: is this
guaranteed (by the standard) to work?  The C standard guarantees that
the digits occur in successive increasing order in the native code
set.  (I believe that this is the only guarantee it makes with regards
to the native code set.)  Does this guarantee hold for wchar_t?  (I
don't believe it does, but I could be wrong.)
--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 09 Aug 1994 15:52:11 GMT
Raw View
In article <JASON.94Aug8234947@deneb.cygnus.com> jason@cygnus.com
(Jason Merrill) writes:

|> >>>>> Ronald F Guilmette <rfg@netcom.com> writes:

|> > Here is what I am talking about:

|> >  wchar_t wc1, wc2;

|> >   ... wc1 = wc2 + 1; ...

|> > I would agree completely that such usage, if it ever appears *anywhere*
|> > in *any* existing C or C++ program, has historically been considered to
|> > be entirely proper, valid and legal.  But does that fact alone imply that
|> > such usage is *ever* a good idea, or that any sane programmer attempting
|> > to write clear maintainable code should ever attempt to misuse the wchar_t
|> > type so blatantly as to treat it as if it were some sort of arithmetic
|> > type (for which arithmetic operations such a +, -, *, /, and % yield
|> > meaningful results)?  NO!

|> Maybe.  Consider:

|> char tolower (char c)
|> {
|>   if ('A' < c && c < 'Z')
|>     return c + 32;
|> }

|> Sure, this useage isn't portable to EBCDIC systems.  Does that mean we
|> should outlaw it?

I don't think the above is really useful, but the following *is*
guaranteed in C:

 char
 todigit( int i )
 {
     assert( i >= 0 && i < 10 ) ;
     return '0' + i ;
 }

All of the digits in the native code set (in locale "C", or
everywhere?) are guaranteed to be consecutive.

Is there a similar guarantee for wchar_t?  E.g.: is the following
guaranteed to work?

 wchar_t
 todigit( int i )
 {
     assert( i >= 0 && i < 10 ) ;
     return L'0' + i ;
 }

If so, then I think that wchar_t has to be an integral type.

--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 10 Aug 1994 16:41:45 GMT
Raw View
In article <32a5s7$50i@paperboy.osf.org> fabre@osf.org (Christian
Fabre) writes:

|> I think that converting an int into its corresponding character
|> should not be done through arithmetics, but through a look-up table:

|> char todigit( int i )
|> {
|>  static const char table[10] = "0123456789" ;

|>  assert( i >= 0 && i < 10 ) ;
|>  return ( table[i] ) ;
|> }

I agree, and always do it this way.  (Also works for hex, with no
change in the code.)  But the standard says that the arithmetic must
work too.  And of course, conversion in the other direction is much
faster using arithmetic (unless you have a table with 256 entries).
--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 10 Aug 1994 09:27:06 -0500
Raw View
In article <32a55j$50i@paperboy.osf.org>,
Christian Fabre <fabre@osf.org> wrote:
>So performing arithmetics on characters (be they "char" or
>"wchar_t") should not be considered good programing practice IMHO.
>
The question is, should your HO or MHO concerning good programming practice
dictate that standard.  I think that the answer is that, provided there are
enough people that believe that it is an acceptable programming practice and
its inclusion does not force people to use it, it should be available.

Many people believe that use of goto is bad programming practice.  I have
even heard people claim that continue and break are just forms of goto and
should be avoided.  Therefore, they may believe that goto should be removed
from the language.  However, its availability doesn't force people to use
it if they believe it to be a poor programming practice.

Given that some people ay do arithmetic on characters and don't find it to be
a poor programming practice, its use should be permitted.

One final point:  portability is not always the goal of a programmer.  The
abaility to program portably and efficiently should be the goal of the
standards comittee, even when these two goals are in direct conflict.  In
otherwords, the standard should allow things that may be non-portable in
terms of character sets as well as provided a standard portable method of
accomplishing the same thing.

>
>Christian.
>
>=====
>   Christian Fabre
>OSF Research Institute   Net: fabre@gr.osf.org
>  2 avenue de Vignate  Tel: +33 76.63.48.90
> 38610 Gieres - France   Fax: +33 76.51.05.32

Stephen Gevers
sg3235@shelob.sbc.com




Author: fabre@osf.org (Christian Fabre)
Date: 10 Aug 1994 09:03:47 GMT
Raw View
In article <JASON.94Aug8234947@deneb.cygnus.com>,
 jason@cygnus.com (Jason Merrill) writes:

|> Maybe.  Consider:
|>
|> char tolower (char c)
|> {
|>   if ('A' < c && c < 'Z')
|>     return c + 32;
|> }
|>
|> Sure, this useage isn't portable to EBCDIC systems.  Does that mean we
|> should outlaw it?

Yes we should outlaw it. The reason is that it is already defined in the following C standards:

 - ANSI-C,
 - POSIX,
 - XPG/1 to XPG/4 from X/Open,
 - SystemV,
 - etc...

Its prototype is:

 #include <ctype.h>

 int tolower(int c) ;

 /* Note that c must be an unsigned char or EOF.
    Note also that the behavior of tolower depends on
    the current locale of the process.  */

So, it won't break only on EBCDIC (where an easy patch to have it work
on both EBCDIC and 7-bits ascii would be "return c - 'A' + 'a'" ), but
it will probably break also on any other character set other from
7-bit ascii, e.g. the ISO-Latin character set.

|> And if you don't outlaw it for narrow characters, I don't believe you
|> should outlaw it for wide characters.  The two types should look as much
|> alike as possible.

Narrrow character (the C "char") can be used to represent two things:

 - a character or

 - a Minimum Addressable Unit of memory.

This means that we should consider that the arithmetics on C char is
avalaible for manipulating memory values as integers, but not to
manipulate plain characters as such, there are a bunch of API functions
to do that. So performing arithmetics on characters (be they "char" or
"wchar_t") should not be considered good programing practice IMHO.


|> Jason

Christian.

=====
   Christian Fabre
OSF Research Institute   Net: fabre@gr.osf.org
  2 avenue de Vignate  Tel: +33 76.63.48.90
 38610 Gieres - France   Fax: +33 76.51.05.32




Author: fabre@osf.org (Christian Fabre)
Date: 10 Aug 1994 09:15:51 GMT
Raw View
In article <KANZE.94Aug9175211@slsvhdt.us-es.sel.de>,
 kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425) writes:

|> I don't think the above is really useful, but the following *is*
|> guaranteed in C:
|>
|>  char
|>  todigit( int i )
|>  {
|>      assert( i >= 0 && i < 10 ) ;
|>      return '0' + i ;
|>  }
|>
|> All of the digits in the native code set (in locale "C", or
|> everywhere?) are guaranteed to be consecutive.
|>
|> Is there a similar guarantee for wchar_t?  E.g.: is the following
|> guaranteed to work?
|>
|>  wchar_t
|>  todigit( int i )
|>  {
|>      assert( i >= 0 && i < 10 ) ;
|>      return L'0' + i ;
|>  }
|>
|> If so, then I think that wchar_t has to be an integral type.

I think that converting an int into its corresponding character
should not be done through arithmetics, but through a look-up table:

char todigit( int i )
{
 static const char table[10] = "0123456789" ;

 assert( i >= 0 && i < 10 ) ;
 return ( table[i] ) ;
}

The same could be done for "wchar_t".

So again, there is no need to do arithemtics on char holding
characters or on wchar_t.

|> James Kanze                                  email: kanze@lts.sel.alcatel.de

Christian.

=====
   Christian Fabre
OSF Research Institute   Net: fabre@gr.osf.org
  2 avenue de Vignate  Tel: +33 76.63.48.90
 38610 Gieres - France   Fax: +33 76.51.05.32




Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Wed, 10 Aug 1994 15:52:39 GMT
Raw View
In article <KANZE.94Aug9175211@slsvhdt.us-es.sel.de>,
James Kanze US/ESC 60/3/164 #71425 <kanze@us-es.sel.de> wrote:
>
>I don't think the above is really useful, but the following *is*
>guaranteed in C:
>
> char
> todigit( int i )
> {
>     assert( i >= 0 && i < 10 ) ;
>     return '0' + i ;
> }
>
>All of the digits in the native code set (in locale "C", or
>everywhere?) are guaranteed to be consecutive.
>
>Is there a similar guarantee for wchar_t?  E.g.: is the following
>guaranteed to work?
>
> wchar_t
> todigit( int i )
> {
>     assert( i >= 0 && i < 10 ) ;
>     return L'0' + i ;
> }
>
>If so, then I think that wchar_t has to be an integral type.
>

 Whether this works depends on the particular character encoding that
is being used by the program. Under Unicode, if I remember correctly, all
of the standard ASCII 7-bit characters are simply widened to 16 bits. In that
case, this transformation remains valid.
 -- Pete




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sun, 7 Aug 1994 01:02:22 GMT
Raw View
Kevin Cooney <cooney@vnet.ibm.com> writes:

>I'm not familiar with the proposal, but how is it better than the
>following:
>
>typedef int bool;
>const bool True( 1 );
>const bool False( 0 );

Overloading works.

 void f(int);
 void f(bool); // only works if `bool' is not the same type as `int'.

>Also, will operator==() still return an int?  Will if() still expect
>an int?

No.  `if', `while', `? :', etc. all expect bools, and `==', `<', `&&', etc.
all return bools.

>What would "True == 5" evaluate to in the proposal (if it is
>even legal)?

The constant is `true' not `True', but ignoring that, it would
evaluate to `false'.  The `true' would be converted to an integer,
giving `1', and the expression `1 == 5' would return `false'.

>Would "int i = True" be legal?

Yes, giving `i' a value of `1'.

>"bool t = 1"? "bool t = 5"?

Yes, both giving `t' a value of `true'.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: mec@shell.portal.com (Michael Edward Chastain)
Date: 7 Aug 1994 03:18:16 GMT
Raw View
My question is: is the pre-processor required to handle booleans?
E.g.

    #if true
 ...
    #endif

    #if false == 0
 ...
    #endif

    #if sizeof(bool) == sizeof(bool)
 ...
    #endif

Should all these constructs evaluate as successful?

Michael Chastain
mec@shell.portal.com




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 7 Aug 1994 07:15:48 GMT
Raw View
In article <31ohs7$gtc@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM writes:
>In article EAp@netcom.com, rfg@netcom.com (Ronald F. Guilmette) writes:
>>>
>>>I'm sorry, but this change *does* make a significant addition:
>>>overloading function calls on these types (which is really a
>>>necessity).
>>
>>Hummm... Lemme see now.  Overloading based upon enum types is in the working
>>paper, and has been for SEVERAL revisions.  (Heck!  Some people have even
>>implemented it.)
>>
>>So if `bool' and `wchar_t' had just been made into enum types, then you
>>would have been able to overload based upon them, yes?  So what's the
>>problem?  (Oh, and by the way, an enum type `bool' was already available
>>in quite a few existing header files.)
>
>Making them into enums would tend to break code and in any event
>require the use of casts.

I believe that this statement is self-evidently false, but even if it
were not, it would be entirely besides the point because the committee's
act of making bool and wchar_t built-in types *itself* broke a lot of
code.  (In particular, it rendered one hell of a lot of existing header
files broken.)

>There is no implicit cast to an enum type.

Yes.  Quite so.  I consider this an asset.

>We expect (in C and C++) to be able to use arithmetic on boolean
>and character types...

WAIT JUST A SECOND THERE!  Whatdaya mean ``we'' Steve???

Let me be crystal clear on this point.  I *never* do arithmetic on what
passes for booleans in the C language (i.e. ints which are being used
as booleans).   I set them to either true or false.  That's it.  That
the way that boolean variables are SUPPOSED to be used.

Furthermore, I don't know any intelligent programmer who misuses booleans
in the manner that you (and other committee members) have suggested that
we ought to be misusing them, notwithstanding all of these nutty ideas
that have come out of the C++ standardization effort, e.g. allowing
pre/post increment/decrement on booleans.

Also, you claim that ``we'' expect to be able to do arithmetic on
character types.  I also find *that* assertion to be utterly without
foundation.  I do arithmetic on arithmetic types.  Period.  Now I *will*
agree that in C (and C++) one is allowed to do:

 char c1, c2;

  ... c1 = c2 + 1;

but so what?  The ``arithmetic'' in this instance (i.e. the addition) is
taking place between two values of type `int'... unless someone has repealed
the integral promotions whilst I wasn't looking!

In short, my point that wchar_t and bool could have been enum types is
still perfectly valid.  They really could have been enum types, and if
they *had* been (sensibly) made enum types then people would have been
able to overload based upon these types *AND* we would have had every
bit as much type saftey as we now have... and probably more (much to
the benefit of those who like to look at and maintain READABLE software).

>The bool and wchar_t types were very carefully integrated into the
>arithmetic types...

I disagree.  I think this was very sloppily done.  Enum types would have
worked, and worked well, but apparently, the committee failed to give
serious consideration to that possibility before deciding to break
essentially every single existing implementation (by making the existing
header files of essentially every single implementation invalid).

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: jason@cygnus.com (Jason Merrill)
Date: Sun, 7 Aug 1994 10:30:43 GMT
Raw View
>>>>> Ronald F Guilmette <rfg@netcom.com> writes:

>> Making them into enums would tend to break code and in any event
>> require the use of casts.

> I believe that this statement is self-evidently false

I believe the opposite.  Consider

bool foo ()
{
  return 1 < 2;
}

if the type of '1 < 2' is int and bool is an enum, you need to cast the
return value explicitly to bool.  Seems clear to me.  This is why bool
cannot be an enumerated type.

typedef int bool;
enum { true, false };

might work, but not

enum bool { true, false };

> but even if it were not, it would be entirely besides the point because
> the committee's act of making bool and wchar_t built-in types *itself*
> broke a lot of code.

So all breakages are equivalent, then?  "Fixing this problem would break
some code" is not a trump argument.

Incidentally, decrementing of bools is not allowed.

> Also, you claim that ``we'' expect to be able to do arithmetic on
> character types.  I also find *that* assertion to be utterly without
> foundation.  I do arithmetic on arithmetic types.  Period.  Now I *will*
> agree that in C (and C++) one is allowed to do:

>  char c1, c2;

>   ... c1 = c2 + 1;

> but so what?  The ``arithmetic'' in this instance (i.e. the addition) is
> taking place between two values of type `int'... unless someone has repealed
> the integral promotions whilst I wasn't looking!

Yes...and then the result of that addition is implicitly converted to type
'char'.  Again, this would break if 'wchar_t' were an enum, introducing a
gratuitous difference between the two character types.

Jason




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 7 Aug 1994 21:21:49 GMT
Raw View
In article <JASON.94Aug7033043@deneb.cygnus.com> jason@cygnus.com (Jason Merrill) writes:
>>>>>> Ronald F Guilmette <rfg@netcom.com> writes:
>
>>> Making them into enums would tend to break code and in any event
>>> require the use of casts.
>
>> I believe that this statement is self-evidently false
>
>I believe the opposite.  Consider
>
>bool foo ()
>{
>  return 1 < 2;
>}
>
>if the type of '1 < 2' is int and bool is an enum, you need to cast the
>return value explicitly to bool.  Seems clear to me.  This is why bool
>cannot be an enumerated type.

My apologies.  I really should have elaborated further on what I was
suggesting.  I really *did* fail to paint the whole picture.

Assume that bool (or perhaps bool_t) is defined as an enum type in some
standard header file (e.g. <stddef.h>), but that the compiler also has
some modest internal understanding of the existance of this type,
independent of that definition (just as is already the case for C
compilers and the types wchar_t and ptrdiff_t).

Now, in the absence of a prior definition of the bool_t enum type, the
compiler, upon seeing an expression like (1 < 2) assumes that it evaluates
to a value of the *internal* (anonymous) enum type... call it @bool_t@...
which then immediately and implicitly gets promoted to `int' in all
contexts where such an expression might validly appear.  (In the absence
of a prior explicit definition of the bool_t type, we need never be con-
cerned with cases such as your example, where a boolean is used to initial-
ize something of type `bool-t' because no such type has yet been declared
or defined in the user's program yet, so it just ain't possible to declare
an object or function having that specific type yet.)

Alternatively, if the compiler has already seen the explicit definition
of the bool_t enum type, then whenever it sees an expression like (1 < 2)
it could know that the value yielded has that (explicitly declared) bool_t
type (and thus, none of the annoying casts you mention would be required).

This approach would have been less draconian than making `bool', `true',
and `false' into keywords.  It would have shared some useful properties
of the solution we ended up with (e.g. the compiler would have had to
have been smart enough to know that (1<2) yields something other than
an int, in the first instance anyway, before any implicit conversions
to int were allowed to take place) but this alternative solution would
NOT have introduced any new keyowrds, and existing header ``standard''
header files would not have been broken overnight.

>> Also, you claim that ``we'' expect to be able to do arithmetic on
>> character types.  I also find *that* assertion to be utterly without
>> foundation.  I do arithmetic on arithmetic types.  Period.  Now I *will*
>> agree that in C (and C++) one is allowed to do:
>
>>  char c1, c2;
>
>>   ... c1 = c2 + 1;
>
>> but so what?  The ``arithmetic'' in this instance (i.e. the addition) is
>> taking place between two values of type `int'... unless someone has repealed
>> the integral promotions whilst I wasn't looking!
>
>Yes...and then the result of that addition is implicitly converted to type
>'char'.  Again, this would break if 'wchar_t' were an enum...

But you see, you have missed my point Jason.  This is exactly a case in
which I actively *want* things to `break'... or, more precisely, we are
now discussing usage which I think that (self evidently) we would *all*
prefer any good ``strongly typed'' language to prohibit (as a way of
helpfully protecting us from ourselves).

Here is what I am talking about:

 wchar_t wc1, wc2;

  ... wc1 = wc2 + 1; ...

I would agree completely that such usage, if it ever appears *anywhere*
in *any* existing C or C++ program, has historically been considered to
be entirely proper, valid and legal.  But does that fact alone imply that
such usage is *ever* a good idea, or that any sane programmer attempting
to write clear maintainable code should ever attempt to misuse the wchar_t
type so blatantly as to treat it as if it were some sort of arithmetic
type (for which arithmetic operations such a +, -, *, /, and % yield
meaningful results)?  NO!  I would argue that it goes violently against
the whole concept of type safety for the language make it easy to misuse
arithmetic operators in conjunction with wchar_t values, as in the example
I have given above.  (I think we will always have to allow (wchar_t+int)
with the wchar_t value first undergoing an implicit type conversion to
some arithmetic type, but I sure as heck cannot see any good justification
for permitting any old type of arithmetic value to be assigned directly
to a wchar_t without explicit conversion, despite the fact that the his-
torical loose typing in C and C++ permited this.)

But that is exactly the kind of usage which you (and Steve Clamage) are
now saying *must* continue to be permissible (for historical reasons, if
for no others).

I say that the stronger typing of C++ (relative to C) has already brought
us to a point where a lot of things that we used to get away with in C
are now considered to be errors when considered as (strongly typed) C++
code.  What I am suggesting is that all historical misuses of the wchar_t
type (if any actually exist in any actual programs... a proposition which
is itself highly dubious) should quite rightly be disallowed (on type
saftey grounds) in C++.  There is nothing particularly revolutionary
about that.  Quite the opposite.  If C++ is *really* to be a type safe
language, then I would say that consistancy demands that *some* effort
be made in the direction of making it harder (though still not impossible)
to misuse values of type wchar_t as if they were arithmetic values (which
they are not).

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: jason@cygnus.com (Jason Merrill)
Date: Sun, 7 Aug 1994 22:18:19 GMT
Raw View
>>>>> Michael Edward Chastain <mec@shell.portal.com> writes:

> My question is: is the pre-processor required to handle booleans?

No.

>     #if true

This becomes '#if 0', unless true is a macro.

>     #if false == 0

This becomes '#if 0 == 0', unless false is a macro.

>     #if sizeof(bool) == sizeof(bool)

This becomes '#if 0 (0) == 0 (0)', unless sizeof or bool are macros.

> Should all these constructs evaluate as successful?

No, just the second one, and that just because the preprocessor converts
all non-macro identifiers used in a directive to 0.  The third one should
produce an error from a conformant preprocessor; Borland's, for one, will
do what you expect for the third case, but that is a non-standard
extension.

Jason




Author: olaf@cwi.nl (Olaf Weber)
Date: Mon, 8 Aug 1994 07:12:52 GMT
Raw View
In article <Cu2Grq.1HHn@hawnews.watson.ibm.com>, Kevin Cooney <cooney@vnet.ibm.com> writes:

> Steve Clamage (clamage@Eng.Sun.COM) wrote:
> : Making them into enums would tend to break code and in any event
> : require the use of casts. There is no implicit cast to an enum
> : type. We expect (in C and C++) to be able to use arithmetic on boolean
> : and character types and not need to cast back the result. When bool and
> : wchar_t are built-in arithmetic types this is true. If they are merely
> : prefined enum types it is not true.

> I'm not familiar with the proposal, but how is it better than the
> following:

> typedef int bool;
> const bool True( 1 );
> const bool False( 0 );

It is all lower-case. :-)

More seriously, you cannot overload `int' and `bool' if you do it like
this.  That can be a problem for some applications, forcing them to
use exceptions, which are rather expensive.  The other problem is that
nearly everyone rolled their own boolean type, often with subtle
differences.  This leads to some gratuitous incompatibilities.

> Also, will operator==() still return an int?

For built-in types `==', `!=', `<', `<=', `>', and `>=' return a bool,
as does `!'.

> Will if() still expect an int?

The conditions in `if', `while', `for' and `?:' expect a bool, as do
`&&' and `||'.

> What would "True == 5" evaluate to in the proposal (if it is
> even legal)?

`true == 5' evaluates to false.

> Would "int i = True" be legal?

Yes, the result is that `i' gets the value 1.

> "bool t = 1"?

Legal, sets `t' to true.

> "bool t = 5"?

Legal, sets `t' to true.

All this should be "as expected" from the way C++ used to work.

-- Olaf Weber




Author: Kevin Cooney <cooney@vnet.ibm.com>
Date: Mon, 8 Aug 1994 13:27:14 GMT
Raw View
I'd like to thank everyone for taking time to respond
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
> Overloading works.
>
>  void f(int);
>  void f(bool); // only works if `bool' is not the same type as `int'.

Ah, but if I then did the following:

 f( 'a' );
 f( (long)1 );

Would either of those be ambigious?  If so, then who would overload
on an int and a bool?  If not, which would be called?

I'm not saying that a standard is a bad thing, I'm just wondering why
it was implemented as a type instead of a typedef or class.  I'm also
curious how bools will work, as I probably probably won't be buying
any C++ manuals any time soon (probably time for me to subscribe to a
C++/OOP journal anyway...).

-Kevin

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Kevin W. Cooney  |
cooney+@cmu.edu  |  http://www.contrib.andrew.cmu.edu:8001/usr/kc2z/home




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Mon, 8 Aug 1994 18:24:53 GMT
Raw View
In article <JASON.94Aug7151819@deneb.cygnus.com> jason@cygnus.com (Jason Merrill) writes:
>>>>>> Michael Edward Chastain <mec@shell.portal.com> writes:
>
>> My question is: is the pre-processor required to handle booleans?
>
>No.
>
>>     #if true
>
>This becomes '#if 0', unless true is a macro.

I'm glad that somebody answered this.  (I was waiting for *someone* to
anwser 'cuz I really didn't know the answer myself.)

Apparently, what Jason is saying is that the (new) built-in literals
`true' and `false' have no special significance to the preprocessor.

I will just note that some folks might consider that as flaw in the
whole (new) bool thing.  I myself am ambivilent.  (I didn't much care
for having bool in the language proper, so why would I want it in
the preprocessor too?  Consistancy?  Maybe.)

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 8 Aug 1994 15:24:59 -0500
Raw View
In article <Cu7xDE.1HCn@hawnews.watson.ibm.com>,
Kevin Cooney  <cooney@vnet.ibm.com> wrote:
:I'd like to thank everyone for taking time to respond
:Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
:> Overloading works.
:>
:>  void f(int);
:>  void f(bool); // only works if `bool' is not the same type as `int'.
:
:Ah, but if I then did the following:
:
: f( 'a' );
: f( (long)1 );
:
:Would either of those be ambigious?  If so, then who would overload
:on an int and a bool?  If not, which would be called?

char promotes to int, so f('a') calls f(int) and long doesn't promote to either
int or bool so it's undefined (not ambiguous).

:=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
:Kevin W. Cooney  |
:cooney+@cmu.edu  |  http://www.contrib.andrew.cmu.edu:8001/usr/kc2z/home

Stephen Gevers
sg3235@shelob.sbc.com




Author: Philip@storcomp.demon.co.uk (Philip Hugh Hunt)
Date: Tue, 9 Aug 1994 02:01:58 +0000
Raw View
In article <rfgCu5LIC.26z@netcom.com>
           rfg@netcom.com "Ronald F. Guilmette" writes:
> >Making them [bool and char_t] into enums would tend to break code
> >and in any event
> >require the use of casts.
>
> I believe that this statement is self-evidently false, but even if it
> were not, it would be entirely besides the point because the committee's
> act of making bool and wchar_t built-in types *itself* broke a lot of
> code.  (In particular, it rendered one hell of a lot of existing header
> files broken.)
>
> >There is no implicit cast to an enum type.
>
> Yes.  Quite so.  I consider this an asset.

If bool was an enum you would have to write:

   bool flag;
   flag = bool(a > b);

instead of

   bool flag;
   flag = a > b;

The enum alternative as well as looking ugly would break a lot of
existing code. I am currently working on a project which can use the
new bool type when it is available, just by removing these 3 lines
from a header file:

   typedef int bool;
   #define true 1
   #define false 0

The enum alternative for bool would be a good idea *if* it had an
implicit cast (reason: don't extend the language if you can add your
new functionality within the language).

--
Phil Hunt




Author: jason@cygnus.com (Jason Merrill)
Date: Tue, 9 Aug 1994 06:41:14 GMT
Raw View
There are two issues here, as I see it:

1) Do you add a boolean type to the language?
2) Do you assign it three keywords that are already commonly used?

You seem to be mostly agreeable to the first point; you agree that the
type of boolean expressions should be something other than 'int'.  You also
argue that it should be an enum.

It seems to me that since you have to extend the compiler anyway, if you're
going to make a boolean type you should make a boolean type.  Variables of
enumeral type can hold any value that their underlying type can, but bool
can only hold 0 or 1.  This way you don't have to worry about whether a
value of 'true' is actually 1, or perhaps 42.

The second point is more contentious.  Would you be more agreeable to
defining a boolean type __bool and requiring some standard header to
provide

typedef __bool bool;
const bool true = 1;
const bool false = 0;

?  You wouldn't have to worry about stepping on user's toes with this one,
since the only keyword isn't in the user's namespace (hmm, got to come up
with a new term for that now) anyway.

Jason




Author: jason@cygnus.com (Jason Merrill)
Date: Tue, 9 Aug 1994 06:49:47 GMT
Raw View
>>>>> Ronald F Guilmette <rfg@netcom.com> writes:

> Here is what I am talking about:

>  wchar_t wc1, wc2;

>   ... wc1 = wc2 + 1; ...

> I would agree completely that such usage, if it ever appears *anywhere*
> in *any* existing C or C++ program, has historically been considered to
> be entirely proper, valid and legal.  But does that fact alone imply that
> such usage is *ever* a good idea, or that any sane programmer attempting
> to write clear maintainable code should ever attempt to misuse the wchar_t
> type so blatantly as to treat it as if it were some sort of arithmetic
> type (for which arithmetic operations such a +, -, *, /, and % yield
> meaningful results)?  NO!

Maybe.  Consider:

char tolower (char c)
{
  if ('A' < c && c < 'Z')
    return c + 32;
}

Sure, this useage isn't portable to EBCDIC systems.  Does that mean we
should outlaw it?

And if you don't outlaw it for narrow characters, I don't believe you
should outlaw it for wide characters.  The two types should look as much
alike as possible.

Jason





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 3 Aug 1994 16:50:15 GMT
Raw View
In article EAp@netcom.com, rfg@netcom.com (Ronald F. Guilmette) writes:
>>
>>I'm sorry, but this change *does* make a significant addition:
>>overloading function calls on these types (which is really a
>>necessity).
>
>Hummm... Lemme see now.  Overloading based upon enum types is in the working
>paper, and has been for SEVERAL revisions.  (Heck!  Some people have even
>implemented it.)
>
>So if `bool' and `wchar_t' had just been made into enum types, then you
>would have been able to overload based upon them, yes?  So what's the
>problem?  (Oh, and by the way, an enum type `bool' was already available
>in quite a few existing header files.)

Making them into enums would tend to break code and in any event
require the use of casts. There is no implicit cast to an enum
type. We expect (in C and C++) to be able to use arithmetic on boolean
and character types and not need to cast back the result. When bool and
wchar_t are built-in arithmetic types this is true. If they are merely
prefined enum types it is not true.

The bool and wchar_t types were very carefully integrated into the
arithmetic types so that existing code working with (reasonable
definitions of) boolean and wide character types will continue to work
unchanged -- or at least that was the intent. New code can take advantage
of their being built-in types.

---
Steve Clamage, stephen.clamage@eng.sun.com






Author: Kevin Cooney <cooney@vnet.ibm.com>
Date: Fri, 5 Aug 1994 14:40:38 GMT
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: Making them into enums would tend to break code and in any event
: require the use of casts. There is no implicit cast to an enum
: type. We expect (in C and C++) to be able to use arithmetic on boolean
: and character types and not need to cast back the result. When bool and
: wchar_t are built-in arithmetic types this is true. If they are merely
: prefined enum types it is not true.

I'm not familiar with the proposal, but how is it better than the
following:

typedef int bool;
const bool True( 1 );
const bool False( 0 );

Also, will operator==() still return an int?  Will if() still expect
an int?  What would "True == 5" evaluate to in the proposal (if it is
even legal)?  Would "int i = True" be legal?  "bool t = 1"?  "bool t =
5"?

Thanks,

-Kevin

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Kevin W. Cooney  |
cooney+@cmu.edu  |  http://www.contrib.andrew.cmu.edu:8001/usr/kc2z/home