These two (as shown here) do the exact same thing, internally. Use
whichever you feel more comfortable with. I never seem to use enums for
unknown reasons.
----------- The opinions expressed in this article are solely mine. -----------
<Insert lame attempt at disclaimer humor>
sss/PU'94 Dept of CS (spe...@phoenix.princeton.edu)/JvNCnet (spe...@jvnc.net)
"There comes a time in the history of every project when it becomes
necessary to shoot the engineers and start production."
>My question is: Which of the two methods - enum's or typedef's - is considered
>better and why?
It depends on your environment. As a general rule, under UNIX it is
preferable to use an enum whenever you have a large number of choices,
because UNIX debuggers get to see enum definitions but don't see
preprocessor macros. In this case it is a little bit iffy, since any
competent C programmer knows that zero is false and non-zero is true.
It may still be useful, however, if you have are passing these things
around a lot, since it will make parameter and return-value displays
much clearer.
-GAWollman
--
Garrett A. Wollman = wol...@uvm.edu = UVM is welcome to my opinions
= uvm-gen!wollman =
That's what being alive is all about. No deity, no higher goal
exists, than to bring joy to another person. - Elf Sternberg
===========================================================================
Josh Mittleman (mit...@watson.ibm.com)
J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY 10598
>In article <92160.2116...@MIAMIU.BITNET>, DK6T...@MIAMIU.BITNET (Dan Karipides) writes:
>>/* number 1 */
>>
>>#define TRUE 1
>>#define FALSE 0
>>typedef int flag;
>>
>>/* number 2 */
>>enum flag={FALSE,TRUE};
>These two (as shown here) do the exact same thing, internally. Use
>whichever you feel more comfortable with.
This is mixing levels of abstraction. You can often write source code
using goto's which generates the same object code as structured code.
This does not mean there is no reason to prefer structured code to free
use of goto.
If you are concerned with type safety, you might want to use enums
rather than macros and ints. For example, if you use an enum, you
should get a complaint from the C compiler if you attempt to assign
anything but 0/FALSE or 1/TRUE to a variable of type 'flag'. If you
use an int, any value is allowed; this could have unintended results
which might be hard to find.
In C++, the type saftey is stronger than in C, to the point where using
an enum for a boolean type is inconvenient. For example:
typedef enum { False, True } boolean;
boolean ok;
...
ok = (x == y) || (a < b);
This code is legal in C, but not in C++. You need an explicit cast
in C++:
ok = (boolean) ((x == y) || (a < b));
The explicit cast subverts the type mechanism, and opens the door to
further undetected errors. For example, if the representation of
boolean were changed, the cast would allow meaningless assignments
without a compiler complaint. You could rewrite this example as
ok = ((x == y) || (a < b)) ? True : False;
This is now completely safe, if a bit unusual. We are suffering the
lack of a built-in boolean type in C/C++.
Some programmers who have experimented with a boolean type in C++,
whether an enum or a class, have concluded that it wasn't worth the
trouble. I would be interested in hearing from any C++ programmers
who have implemented a boolean type and found it beneficial.
--
Steve Clamage, TauMetric Corp, st...@taumet.com
Vice Chair, ANSI C++ Committee, X3J16
The enum version is preferable:
o enum improves readability. using enum makes it clear that the constants
(eg TRUE & FALSE) are related. The constants are defined in one spot.
If, later on, we want to allow for MAYBE, we can just add it to our
list (eg {FALSE, MAYBE, TRUE} ) without having to stop and think what
value MAYBE should have.
o the compiler can enforce strong type checking with enumerated types.
we can enlist the compiler's help to make sure that we don't assign
some nonsense value or magic number to a flag that should always be
TRUE or FALSSE.
o enumerated types have the advantage of
being symbols, available to the debugger, whereas
#defines never even make it to the compiler.
-dk
typedef int boolean;
const boolean FALSE = 0;
const boolean TRUE = 1; // or perhaps !FALSE
It was the only combination that (1) avoided using the preprocessor (and
its possible side-effects) and (2) avoided typecasts needed for enum
boolean expressions. The downside is that this only works with C++ and
ANSI C - not plain K&R C, and the debugger still sees them as ints.
Treating ints as booleans as both C and C++ do is both both quite useful
and quite annoying, depending on the kind of code you're writing.
Well, at least the boolean typedef documents the intended use of a var.
-- Parag Patel <pa...@Netcom.COM>
In general, I prefer enums for cases such as this, for reasons of
type safety. In the specific case of a Boolean type, I prefer to
use the typedef, for the reason given by Steve (ability to assign
the result of a logical operator to a Boolean variable).
But it's probably better to use static const variables for the
values, not macros:
typedef int Boolean;
static const Boolean true = 1;
static const Boolean false = 0;
This adds a bit of type safety (now false can't be used where a
pointer is expected, for example), and doesn't prevent true
and false from being used in other namespaces.
|Some programmers who have experimented with a boolean type in C++,
|whether an enum or a class, have concluded that it wasn't worth the
|trouble. I would be interested in hearing from any C++ programmers
|who have implemented a boolean type and found it beneficial.
I haven't tried an enum or class, but would agree that they probably
cause more trouble than they're worth. But I do find a Boolean
typedef to be useful. The main advantage is the extra documentation
in function prototypes. After
int foo();
Boolean bar();
it's fairly clear that foo returns a number and bar returns
a yes/no indication. (Yes, these should be indicated in comments,
but it's helpful to see it in the return types as well.)
Also, when a success/failure indication is returned in
an int result, there are two common conventions for indicating
success: returning 0 or returning non-zero. It's often hard
to remember which convention is used by each routine you call.
With a Boolean result, it's quite uncommon to use false to
indicate success, so there's less chance of confusion.
--
Patrick Smith
uunet.ca!frumious!pat
pat%frumio...@uunet.ca
I don't think its worth doing for bools, but I think it can be worth
doing for other simple cases -- rather than just using unsafe typedefs
for everything! The point being that you can quasi-derive multiple classes
from int which are each compatible with int, but which cannot be easily
accidentally substituted for one for the other.
class boolean
{
int i;
public:
boolean() : i(0) {}
boolean(const int ii) : i(ii) {}
operator int&() { return i; }
boolean& operator=(int ii) { i = ii; return *this; }
};
class trinary
{
int i;
public:
trinary() : i(0) {}
trinary(const int ii) : i(ii) {}
operator int&() { return i; }
trinary& operator=(int ii) { i = ii; return *this; }
};
#define TRUE 1
#define FALSE 0
boolean test1(int a, int b, int x, int y)
{
boolean ok;
ok = (x == y) || (a < b);
return ok;
}
boolean isNotTrue(boolean b)
{
return !b;
}
main()
{
isNotTrue(TRUE);
trinary t3=TRUE;
isNotTrue(t3);
return 0;
}
/*
This is probably not sufficient justification for class bool -- but it
could be justified for other primitive-derived classes, rather than
just always typedef'ing to a primitive
*/
I regret to inform you that it does *NOT* work in ANSI C. The reason for
this is that
const boolean FALSE = 0;
is a "DEFINITION", and that a variable may be defined in at most one
"translation unit". As long as your program has at most *one* *.c file
that #includes "boolean.h", you are safe, but if two *.c files #include
it, your program is illegal. It won't work with the PC compilers I've
tried (the linker doesn't like it) and it won't work with the UNIX
compilers I've tried (guess what, the linker doesn't like it).
What _would_ work is
static const boolean FALSE = 0;
static const boolean TRUE = !0;
That would work with K&R C, with one change:
/* File: boolean.h */
#ifndef __STDC__
#define const
#endif
typedef int boolean;
static const boolean FALSE = 0;
static const boolean TRUE = !0;
But this is overkill. It is important to realise that 'const' in ANSI C
does not mean what it does in C++ (I refer you to the C++ ARM to find out
what the differences are), and it doesn't declare constants in the sense
of Pascal or Ada. All it does is declare read-only variables. In
particular, any expression that uses TRUE or FALSE defined this way is
__NOT__ an integer constant expression, still less a #if expression.
So
#include <boolean.h>
boolean do_trace = FALSE;
is _illegal_, because a top-level initialiser must be a constant expression.
It is just plain silly to use the preprocessor (#include is after all a
preprocessor directive) in order to "avoid using the preprocessor"!
Whatever TRUE and FALSE are, we would like them to be legal initial values
for top-level "boolean" variables. There are only two choices: macros and
enumeration types. Macros have the advantage that you can use them in
#if expressions:
#define do_trace FALSE
...
#if do_trace
...
#endif
Enumerations have many disadvantages. (They really don't buy you much in
ANSI C; they are just enough different from other integral types to be a
nuisance without being different enough to make anything safe.)
Bite the bullet. Do what has been working in C programs for years:
#undef FALSE /* just in case */
#undef TRUE
#define FALSE 0
#define TRUE 1
--
You can lie with statistics ... but not to a statistician.
[ discussion about typedefs vs. enums bluntly deleted ... ]
|Some programmers who have experimented with a boolean type in C++,
|whether an enum or a class, have concluded that it wasn't worth the
|trouble. I would be interested in hearing from any C++ programmers
|who have implemented a boolean type and found it beneficial.
I don't want to start another religious war on this, but IMHO a boolean
type in C/C++ is simply useless. In my `philosophy' (ahem) there's just
one `true' value and there are many ways for a program to fail, so I
defined:
#define TRUE 0
#define FALSE (-1)
I use all the other non-zero values to indicate the type of failure,
negative numbers being severe errors, positive numbers being just
completion codes or warnings. A couple of years ago I started grouping
these values, using the low byte for the particular error/status
and the next higher bytes for the `class' in which these conditions
could occur. It works fine for me ...
BTW the above two definitions force me to type something like:
if (foo() == FALSE) /* etc */
instead of:
if (!foo()) /* etc. */
but I don't care, I think an exclamation sign at the beginning
of a sentence looks silly anyway ;-)
Just my $0.02
kind regards,
Jos aka j...@and.nl
As a general rule, under UNIX it is preferable to use an enum
whenever you have a large number of choices, because UNIX debuggers
get to see enum definitions but don't see preprocessor macros.
... unless you use CodeCenter or ObjectCenter, my company's
debuggers/programming environments, which allow you to evaluate full C
or C++ expressions, including macros, interactively.
----
Sam Kendall
CenterLine Software, Inc. (formerly Saber Software)
But those cost so much they might as well not exist as far as most
programmers are concerned. This discussion is about real programming,
not pie in the sky.
One cute way to define the values is this:
#define TRUE (1==1)
#define FALSE (1==0)
in case you're bored with 1 and 0.
--
-- jwh
Why is this better than:
typedef enum {false, true} boolean_t;
)
)One cute way to define the values is this:
)
)#define TRUE (1==1)
)#define FALSE (1==0)
)
)in case you're bored with 1 and 0.
)--
)
) -- jwh
Also, does anyone know why:
{
short i;
for(i=0;i<64;i++)
v1[i]=v2[i]+v3[i];
}
is worse than
{
int *v1i,*v2i,*v3i;
for(v1i=&v1[64],v2i=&v2[64],v3i=&v3[64];(v1i--)>v1;)
*v1i=*(--v2i)+*(--v3i);
}
Is my compiler lacking something?
--
Urban Koistinen - md85...@nada.kth.se
I find this strange, and don't really understand the problem (though I
acknowledge that it exists.) Why is management unwilling to spend $3,500
to enhance a programmer's productivity, especially with something like
a fancy debugger which could be shared amoung several programmers.
This is equivalent to at most 50-100 programmer hours (burdened) which
should be recovered in a year.
Do managers not believe in the productivity increase?
Do they really want a larger work force with lower productivity?
Are capital funds from a different budget and less available than
salary?
I'm not trying to make a political point, I'm trying to understand
the situation.
Data anyone?
--
Michael S. Ball (mi...@taumet.com)
TauMetric Corporation
FOR THE FOLLOWING CODE:
#include <stdio.h>
typedef enum
{
TCPIP = 0x0800,
ARP = 0x0806
} Packet_type;
Packet_type c;
void main(void)
{
printf("Size of Packet_type is %d\n", sizeof c);
}
YOU MIGHT GET:
Size of Boolean is 2
OR
Size of Boolean is 4
DEPENDING ON THE COMPILER AND/OR COMPILER SWITCHES.
This is mainly a problem (like I said) in external protocols such as those
dealing with interprocessor, or inter-machine. Many C++ compilers come
with switches that will allow you to specifically set the size of an
enum ("treat enum as int").
If the enum is used internally (as part of a software package running
on one processor), then I like using "enums" since debuggers usually
know about them and will display the values of variables in terms of
the enumerated type rather than value.
A message such as:
status = MEM_FAIL
is much nicer than:
status = 114
Just my thoughts,
jC
--
__/o___~_ James Card (Firmware Engineer)
(________| Nothin' like Sybus Corporation
@ @ top down 2300 Tall Pines Dr. Suite 100
weather... Largo, Fl 34641 (813) 535-6999
[with the caveat that I'm talking about US managers in general....]
| Do managers not believe in the productivity increase?
No. They believe that low productivity is due to a lack of motivation
of the workers. The workers are only using lousy tools as an excuse
to be lazy. If the manager was doing the job, the job would be done,
in spite of any problems with the tools.
| Do they really want a larger work force with lower productivity?
The manager's "reality" is that they have to work with lazy unmotivated
workers. Thus the manager reluctantly suggests to senior management that
this manager be allowed to hire more workers to get the job done. The
ability of the manager to handle all these large numbers of lazy unmotivated
workers in turn demonstrates the competence of this manager, demonstating
that he should be promoted so that he can manage even more of these lazy
unmotivated workers.
| Are capital funds from a different budget and less available than
| salary?
The manager demonstrates to senior management his competence by keeping
capital expenses down to the incredibly low low value of a $1.29 per
employee per year.
|I'm not trying to make a political point, I'm trying to understand
|the situation.
Read Deming, for a start. Or watch his video tape set. It clarifies
a *lot* of issues. Read especially about the Red Bead Test. Now
excuse me while I go paint some white beads red -- management never
seems to notice the difference....
Oops - sorry about that. I knew that but typed in ANSI C without paying
attention. I meant just C++. The static trick works too.
Actually, this method of using const vars can cause similar problems in
C++, but most implementations are usually smart about figuring out how
the var (TRUE or FALSE) is used and effectively removing it from the
resulting object file by using its value. (I think that gcc also
behaves this way.) Add "&TRUE" in the code somewhere and space will
have to be allocated causing much fun.
One advantage of the #define - stuff like &TRUE is caught.
-- Parag
In the case of TRUE/FALSE there may be a good argument
for using neither. Use 0 for false and 1 for true. These are
always correct and cannot cause any namespace conflicts.
Note also that assigning an integer to an enum variable
is illegal. As such, assigning the result of a comparison
would not be legal, a serious problem for using enums.
enum bool {false, true};
bool result = 1<0; // syntax error
Since using many incompatible systems with different
ideas about booleans I have given up and use int everywhere now.
--
;----------------------------------------------------------------------
JOHN (MAX) SKALLER, max...@extro.ucc.su.oz.au
Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Mmm, Mmm - that pie up here tastes SO good... perhaps a programmer working
out of her or his garage might find it tough to make the initial investment,
but any company doing much C or C++ programming is going to save the initial
investment in about 3 man weeks of heavy use of these tools I would guess.
Thus - if you have 20 simultaneous license for your 100 programmers, in
about 6 days or less you will have made back what you paid . Just think
of all the compiles and printfs you can do without using a tool like
this (or other similar tools). And the extra error checking, at load and
run time, to me is worth quite a lot.
--
Larry W. Virden UUCP: osu-cis!chemabs!lvirden
Same Mbox: BITNET: lvirden@cas INET: lvi...@cas.org
Personal: 674 Falls Place, Reynoldsburg, OH 43068-1614
America Online: lvi...@aol.com
> ...
> Note also that assigning an integer to an enum variable
> is illegal. As such, assigning the result of a comparison
> would not be legal, a serious problem for using enums.
>
> enum bool {false, true};
> bool result = 1<0; // syntax error
> ...
This is one of the things that makes the ansi standard look more like
pascal, a bunch of stupid rules that lets the compiler attack you :)
An other is the rule that stops you from using short statements like:
if (something) foo=7,return;
now you have to write:
if(something) foo=7,return,4711;
;-)
--
| d91...@nada.kth.se | The good reputation the Mac has gotten is totaly
| Johan Danielsson | undeserved, laid on by people who don't understand,
| who have not gotten in there and tried anything.
>[deleted]
>DEPENDING ON THE COMPILER AND/OR COMPILER SWITCHES.
>
>This is mainly a problem (like I said) in external protocols such as those
>dealing with interprocessor, or inter-machine. Many C++ compilers come
>with switches that will allow you to specifically set the size of an
>enum ("treat enum as int").
>
Not just enums. ALL of C/C++ structures have this problem.
To circumvent it you MUST break the type system. This is best
done I think by packaging the 'standard layout->internal machine
layout' stuff away somewhere, so the breakages are isolated.
This precisely what portable database systems do, they
provide 'GETINT(fieldnumber)' type functions. This is, however,
and extreme pain: to read in a database record you must
create a conversion procedure to unpack it. (and another
to repack it).
This could be done by the compiler for structs with only
basic types in them (int, float, etc). But there would have to
be a universal layout agreed upon. ANSI committee for C++ is
not going to do this.
In article <92160.2116...@MIAMIU.BITNET>, DK6T...@MIAMIU.BITNET (Dan Karipides) writes:
>/* number 1 */
>
>#define TRUE 1
>#define FALSE 0
>typedef int flag;
>
>/* number 2 */
>enum flag={FALSE,TRUE};
The enum version is preferable:
o enum improves readability. using enum makes it clear that the
constants (eg TRUE & FALSE) are related. The constants are
defined in one spot. If, later on, we want to allow for MAYBE,
we can just add it to our list (eg {FALSE, MAYBE, TRUE} )
without having to stop and think what value MAYBE should have.
Perhaps.
o the compiler can enforce strong type checking with enumerated types.
we can enlist the compiler's help to make sure that we don't assign
some nonsense value or magic number to a flag that should always be
TRUE or FALSSE.
The compiler can never enforce strong type checking on boolean
values, because in C and C++ the result of boolean operations
such as ||, &&, etc are ints, and because the condition in
statements like if (condition) must be coerced to an int.
o enumerated types have the advantage of
being symbols, available to the debugger, whereas
#defines never even make it to the compiler.
This is nice. A static const int variable is another way to
make the symbols available to the debugger:
static const int true = 1;
static const int false = 0;
This works nicely as long as the compiler doesn't complain
about unused static variables.
In ANSI C, this may not provide as much type enforcement as would be thought.
According to X3Jll/90-013 (ANSI C def) Sect. 3.1.2.5 line 17:
An enumeration comprises a set of named integer constant values.
And section 3.1.3.3 line 6:
An identifier declared as an enumeration constant has type int.
And section 3.5.2.1 line 40:
Each enumerated type shall be compatible with an integer type;
Basically, this is stating that enumerated types and constants are to
be compatible with integers. Therefore, anywhere prototypes specify
the use of an enumeration, an integer can be legally used. Since an
integer can be used in the place of an enumeration and all integers
are compatible with enumerated types, this results in allowing a defined
enumerated type (which is interchangeable with integers) to be used in the
same place as another enumerated type (since it is also interchangeable with
integers).
Therefore, in certain situations, enumerated constants of different
enumerated types are completely interchangeable.
Corrections and different interpretations are welcomed,
Jeff Caldwell | HP Calif. Lang. Lab
>In article <1992Jun11.1...@tfs.com> er...@tfs.com (Eric Smith) writes:
>>
>> .. reference to CodeCenter deleted
>>
>>But those cost so much they might as well not exist as far as most
>>programmers are concerned. This discussion is about real programming,
>>not pie in the sky.
>I find this strange, and don't really understand the problem (though I
>acknowledge that it exists.) Why is management unwilling to spend $3,500
>to enhance a programmer's productivity, especially with something like
>a fancy debugger which could be shared amoung several programmers.
I'm not familiar with CodeCenter per se, but most software is
still licensed per user one way or another (per machine, floating
license, etc.)...so you couldn't really expect ot share one copy
among several programmers.
>This is equivalent to at most 50-100 programmer hours (burdened) which
>should be recovered in a year.
> Do managers not believe in the productivity increase?
Most managers will believe enough in the concept of a productivity
increase from a good debugger to ask for it, but usually the
authority for a specific captical expense item like this ends up higher
up in the management chain, where maybe the belief isn't as strong..
> Do they really want a larger work force with lower productivity?
No; they'll go for the same size workforce with lower productivity
and then probably live with schedule slips, because that's off in
the future, and the captial expense is NOW (actually, they won't
accept the later schedule now, but they'll find a way to live with
it when it happens).
> Are capital funds from a different budget and less available than
> salary?
Almost certainly - this has been the case anywhere I've worked; any
"captial expenditure" had to be fought for, and _software_ captial
expenditures over, say, $1000 involves particular pain. For example,
I've had MUCH less trouble justifying a $25,000 PC-based ICE than a
$20,000 integrated bug-tracking system/revision control system, even
though the long-term rewards of the latter are likely to far outstrip
those of the former.
Now mind, I'm not saying that everyone works this way. I'm well aware
that I've not worked for a list of very good companies (my loss). And I
haven't worked for anyone that considered themselves a software company -
there was always a hardware component. Maybe this explains the
mindset...or maybe not.
--
Mats Wichmann
Systems Software Consultant
alruna!ma...@ossi.com (or ma...@netcom.com)
Maybe some do, but this is not necessary. A good database system will give you
the structure/class with the correct alignment for the machine you are on.
Stuart
: Stuart MacMartin email: s...@bnr.ca :
: Bell-Northern Research phone: (613) 763-5625 :
: PO Box 3511, Stn C, Ottawa, K1Y-4H7, CANADA Standard disclaimers apply. :
> Do managers not believe in the productivity increase?
Managers often don't understand the problem enough to understand productivity increase due to better tools.
> Do they really want a larger work force with lower productivity?
This I doubt.
> Are capital funds from a different budget and less available than
> salary?
In my environment salary dollars are separate from O&M dollars and from capital dollars. I can drop $2-3000 on a trip to discuss a project without much justification. Buying a $3000 tool requires that I budget a year in advance and hope I get the money. Whether this is because of management's view or the reason for it depends on what level of management you are on I guess (grin).
Larry D. Marshall lmar...@pnfi.forestry.ca
Petawawa National Forestry Institute +1 (613) 589-2880
Forestry Canada, Box 2000 +1 (613) 589 2275 FAX
Chalk River, Ontario K0J 1J0
> 3) PC pricing. Everyone seems to agree that in the long run Unix
> prices will sink towards those on the PC. PC programming
> environments cost hundreds, not thousands, of dollars. Competition
> will drive this.
Promise??? Should I wait to order Centerline :-) Seriously, there is a Catch-22 to all this in that at least in some environments, selling Unix boxes is tough, not due to the price of the hardware, but due to the software. If the prices were to fall the market would open up much wider.
Doesn't this method allocate global storage for FALSE and TRUE?
What I think is so cool about C++ is the compiler will not allocate global
storage unless it sees you taking the address of the variable (and you
get the type checking).
dk
Not quite necessarily; the abstract ANSI C machine certainly would, but a
sufficiently smart compiler might be able to get away with not doing so.
However, in ANSI C you would *not* be entitled to use FALSE and TRUE in
contexts which require an integral constant, because they name variables
(unvariables?).
Doesn't this method allocate global storage for FALSE and TRUE?
What I think is so cool about C++ is the compiler will not allocate global
storage unless it sees you takiong the address of the variable (and you
>Doesn't this method allocate global storage for FALSE and TRUE?
Usually not, unless you do something that requires taking the address of
one of these in your code, ie "int *ip = &TRUE", "int &ir = FALSE", etc.
Both g++ and cfront optimize using simple int consts such as these.
However, as others have pointed out, #define is still the best approach.
I guess there's still no escape from the preprocessor.
-- Parag Patel <pa...@Netcom.COM>
Despite my wish for a boolean type, I disagree. What happens
if some other class library defines TRUE or boolean?
IMHO
1) Use 'int' when you mean boolean.
2) Use '0' when you mean false
3) Use '1' when you mean true
This is guarranteed to be correct in standard C and C++, and cannot
cause conflicts (but respect other libraries use of enums, or
boolean classes of course, just don't add any more confusion.)
Similarly, use 0 and not NULL for a null pointer, if you must
distinguish int and void* which are both 0 do so with an
explicit visible cast
f((int)0);
f((void*)0);
I have decided this after bitter experience: my own definitions
conflict with Windows header files, and with almost
every class library provided by a third party. MY class library,
when released will NOT define boolean!
This is a good reason for the ANSI committee to standardize the definition
of Boolean and standardize the header file Boolean should be defined in
(e.g. ctype.h). I prefer if they use enum, but #defines are fine with
me. Just so third-party venders do not find it necessary to create their
own Boolean type. I think NULL is already standard (in stdlib.h?).
- Pablo
------------------------------------------------------------------------
Pablo Halpern (617) 290-3542
HP Waltham pab...@hpwarq.wal.hp.com
I am self-employed, so my opinions *do* reflect those of my employer.
However, they may not reflect the opinions of my client.
------------------------------------------------------------------------
Yes, ANSI C specifies that NULL be defined, in several headers
(not that this seems to have reduced the confusion surrounding
its correct #definition).
It's too late to standardize a boolean type, partly because the
ANSI C committee tried mainly to standardize existing practice,
and partly because there are so many conventions already in use.
What John's lament does illustrate, to perfection, is that no
responsible vendor of add-on libraries should be defining NULL,
TRUE, or FALSE (or other obvious things like Min() and Max()) in
any of its header files. It's bad enough if the vendor's
definitions clash with the user's. But what if the poor user is
trying to use two different vendors' (incompatible) header files
simultaneously?
It's extraordinarily annoying to use third-party header files
which were clearly tested by their manufacturers only in little
toy test programs, with no thought given to their integration
into large systems. (Third-party library routines which print
error messages directly to stderr are another sore point...)
I've used a number of data acquisition cards and systems for
which I abandoned the supplied driver libraries and wrote my own,
because the ones supplied were simply unusable.
Steve Summit
s...@adam.mit.edu
I currently use the equivalent of
typedef int boolean;
enum { FALSE, TRUE };
This obviously works well for ANSI C and K&R, and I think it is
correct for C++ too.
Are there cases where the enum definition of FALSE/TRUE fails,
but where the "const boolean" approach succeeds?
Using a CFront 2.1 derivative, I fail to fail with the enum definition.
--
--------------------------------------------------------------------------
| Johan Bengtsson, Telia Research AB, Aurorum 6, S-951 75 Lulea, Sweden |
| Johan.B...@lulea.trab.se; Voice:(+46)92075471; Fax:(+46)92075490 |
--------------------------------------------------------------------------
Why not just "typedef enum {FALSE, TRUE} boolean;"? And, what's the
enum doing there if there's no enum tag name, or variable declaration?
Is that legal?
(Oh to have ANSI for home and office,... Maybe I should just bring
it home, since I don't read c.l.c in the office, and I can't write ANSI
code at work?)
Try it on this:
int c;
for (c = 0; c < 128; c++)
{
if (isprint(c) == TRUE)
printf("%c is printable.\n", c);
else
printf("Character \\%03o isn't printable.\n", c);
}
] This obviously works well for ANSI C and K&R, and I think it is
] correct for C++ too.
As long as your range of booleans really is guaranteed to be (0,1).
That seems like an awfully dangerous assumption to me. And, besides,
if (foo(x))
just seems a lot clearer and more predictable than
if (foo(x) == TRUE)
for example. Not to mention the previously mentioned problem of nice
vendors defining TRUE and FALSE for you in headers (how kind!).
] Are there cases where the enum definition of FALSE/TRUE fails,
] but where the "const boolean" approach succeeds?
No, they both suck as the same things. Using const's, though, has
the additional charm of being slower (if your optimizer's weak, or your
machine doesn't have enough registers to throw at the problem).
-- Bill K.
Bill Kaufman, | "...all conscious species are plastic and
Corporate Lackey | all plastic species are conscious."
wkau...@us.oracle.com | -- Yew-Kwang Ng
Shhhhhh.... thank you. Now, please see Section 11 of the FAQ list.
--
Mark Brader "In the rough, roguish, early days, when men were
SoftQuad Inc., Toronto men, women were women, and pointers were ints,
utzoo!sq!msb Real C Programmers wouldn't even bother to invent
m...@sq.com tags for structs ..." -- Steve Summit
This article is in the public domain.
Yes. Given C's lax typing using enum in this fashion is a good way to
reduce the amount of typing over using #define. e.g.,
enum
{
OK,
ERR_STUFFED,
ERR_BROKEN,
... more error codes
};
This is less typing than...
#define OK 0
#define ERR_STUFFED 1
etc, etc...
--
Andy Newman (an...@research.canon.oz.au)
>What John's lament does illustrate, to perfection, is that no
>responsible vendor of add-on libraries should be defining NULL,
>TRUE, or FALSE (or other obvious things like Min() and Max()) in
>any of its header files. It's bad enough if the vendor's
>definitions clash with the user's. But what if the poor user is
>trying to use two different vendors' (incompatible) header files
>simultaneously?
Even more reprehensible is putting these sorts of things in _standard_
headers. IBM #defines TRUE and FALSE in stdio.h on their RS6000 series
AIX operating system. This breaks every program that #defines TRUE or
FALSE and #includes stio.h, i.e., probably the majority of existing
C programs.
This also violates The Standard, by trouncing on the
user's name space in a standard header.
--
|| tom stockfisch, biosym technologies t...@chem.ucsd.edu