[comp.lang.c] BOOLEAN as enum

al@gtx.com (Alan Filipski) (03/29/90)

It has been proposed around here to define a Boolean type as

          typedef enum {FALSE, TRUE} BOOLEAN;

to me there seems to be very little difference between this and the more
usual

          #define FALSE 0
          #define TRUE 1
(and, optionally, either typedef int BOOLEAN or typedef char BOOLEAN)


The only difference I see is that lint could complain about some
clashes, as in

           BOOLEAN p() 
          { 
             return 99; 
          } 

or



           BOOLEAN x;
           x = 10; 

which complaints might be useful.  however, lint would then also
complain about things like:

          x = (a==b);

or
           BOOLEAN p()
          {
             return (a==b);
          }


which one probably does not want to see complaints about
(but which could be circumvented with a logically gratuitous cast).

anyway, my question is this: aside from possible lint messages,
does the ANSI model for enums imply any difference between the
enum or #define approach to TRUE/FALSE?  My personal opinion is that,
since neither approach provides a real BOOLEAN type, one
should stick with customary usage.  Comments?



  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ( Alan Filipski, GTX Corp, 8836 N. 23rd Avenue, Phoenix, Arizona 85021, USA )
 ( {decvax,hplabs,uunet!amdahl,nsc}!sun!sunburn!gtx!al         (602)870-1696 )
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bob.Stout@p6.f506.n106.z1.fidonet.org (Bob Stout) (04/05/90)

In an article of <4 Apr 90 15:45:52 GMT>, (Michael T. Sullivan) writes:

 >Okay, put another way "func() != FALSE" doesn't necessarily mean that
 >func() is true, since func() can now return ERROR.  Since when is something
 >true or false or something else?  It should either be true or false--there
 >are only two answers to a yes-or-no question.

  OK, but you ultimately have control over what func() returns so you have the  
ability to assure it returns either 1 or 0, just as you do now. This is why I  
suggested the BOOL macro, so you could write:

typdef enum {ERROR = -1, FALSE, TRUE} logical;
#define BOOL(x) (!(!(x)))

logical func()
{
        int x;
        ...
        if (bad_stuff)
                return ERROR;
        ...
        return BOOL(x);         /* always 1 or 0        */
}

main()
{
        int result;
        ...
        if (ERROR == (result = func()))
                handle_it();
        else if (TRUE == result)        /* BOOL obviates !FALSE tests   */
                do_true_stuff();
        else    do_false_stuff();
        ...
}

  Now if you're concerned about what func() returns, simply process the return  
value with BOOL and omit the error return. Since `logical' is a typedef of an  
enumeration, the values you assign are really nothing more than glorified  
#defines anyway - enum's evaluate to int's and can therefore assume any value  
whatsoever. Like any #defined value, if you don't want to use ERROR, no one's  
twisting your arm - it's just there if you want/need it. Don't criticize the  
shorthand when the language is incapable of expressing what you mean. 

seanf@sco.COM (Sean Fagan) (04/11/90)

In article <986@mti.mti.com> adrian@mti.UUCP (Adrian McCarthy) writes:
>  if (!strcmp(s1,s2))  /* YUCK!!! */

Why "YUCK!!!"?  This is perfectly reasonable code, with wide-spread usage.
To me, it's now more readable than "if (strcmp (s1, s2) == 0)", although I
will admit I'm a bit weird.

>what the function does and didn't mistake for a boolean function.

Oh.  I see.  You simply don't understand C.  Now I understand your post.

>Assuming:  f1 = fopen("data.dat","r"); test like this:
>
>  if (f1 = NULL) { /* handle error */ }
>not like this:
>  if (!f1) { /* handle error */ }

Of course not; these mean two different things.

>Similary: if (count > 0) {}, not: if (count) {}.

These are only equal if count is unsigned, unless the programmer *knows*
that count will never be negative.

-- 
-----------------+
Sean Eric Fagan  | "It's a pity the universe doesn't use [a] segmented 
seanf@sco.COM    |  architecture with a protected mode."
uunet!sco!seanf  |         -- Rich Cook, _Wizard's Bane_
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

chrisf@uswmrg2.UUCP (Chris Fedde) (04/12/90)

Just a dumb question here...
What ever hapend to the K&R field operators?  Why does everyone go to all
the work of making up bit manipulation macros when the language supports
small integer values in native syntax?

Chris Fedde
uswmrg2!chrisf@uswat.uswest.com   

-- 
	  _               ___
	 / ' /_  _ .     /_ _  _/ _/ _
	 \__/ /_/(/_/)_ /  (/_(/_(/_(/_

exspes@bath.ac.uk (P E Smee) (04/12/90)

In article <1990Apr6.230447.22818@aqdata.uucp> sullivan@aqdata.uucp (Michael T. Sullivan) writes:
>:From article <1990Apr6.102819.9379@bath.ac.uk>, by exspes@bath.ac.uk (P E Smee):
>> Depends on what you're writing.  I frequently find it appropriate to
>> have THREE possible answers to a yes-or-no function.  Loosely described
>> as 'TRUE', 'FALSE', and 'I don't know'.
>
>If there are three answers, then it isn't a TRUE/FALSE question so
>the names "TRUE" and "FALSE" shouldn't be used.  
>If there are more answers then pick other names.

I think we're becoming theological here.  I understand your position,
and can see the rationale behind it.  On the other hand, my viewpoint
is that for most useful TRUE/FALSE questions, there is actually a third
possible 'answer' which loosely speaking translates as 'I'm not able to
determine which is the case'.  Maybe because of incomplete data; maybe
because of a hardware limitation; maybe because you've given me invalid
arguments.  And so on.

That is, the question is actually a TRUE/FALSE question, but there is
some probability that it will be (in some contexts) 'unanswerable' or
indeterminate.  Adding a third return value provides a handy way of
handling these cases.  (I see it, in some sense, as analogous to IEEE
NaN's for floating point.  Though the analogy is a bit weak since my
'Can't tell' value is not automagically supported by the hardware.)

As I said elsewhere, though, what mostly concerns me is that any given
chunk of code is written consistently -- just in case I have to take it
over.  If you prefer tri-state 'two-states' (I do) then fine, use them.
If you don't like them, use some other method of exception handling.
Please don't mix them haphazardly.

-- 
Paul Smee, Computing Service, University of Bristol, Bristol BS8 1UD, UK
 P.Smee@bristol.ac.uk - ..!uunet!ukc!bsmail!p.smee - Tel +44 272 303132