Topic: The bool portability problem


Author: guus@proxim.franken.de (Guus C. Bloemsma)
Date: 1995/04/22
Raw View
In article <9510911.27608@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus
Henderson) writes:
> That is a bad example, since the name `_BOOL_H_' (like others starting
> with an underscore and an uppercase letter) is reserved for use by the
> implementation.  You should use plain `BOOL_H' or, if you must,

Is this defined in the standard (draft), or is it an
implementation-specific convention?

Does it only apply to macros, or are all identifiers starting with
underscore and uppercase letter reserved?

TIA, Guus.





Author: Timothy Sharpe <gadget@halcyon.com>
Date: 1995/04/21
Raw View
> Personally, if there's no predefined bool type, I see nothing wrong with
>
> const int FALSE = 0;
> const int TRUE = 1;
>
> Defining TRUE as !FALSE rather than 1 doesn't add any clarity, IMHO.
>
> The important thing to remember is to avoid comparing boolean values to
> FALSE or TRUE; (x == TRUE) can be false even if x is logically true.

So, you'd rather stick to 0,1 and give up the ability to use (x == TRUE)
as a legal comparison?  That implies you have to use (!(x == FALSE)).

Let me restate my position on Boolean's a bit more clearly.

Define TRUE "all ones"
Define FALSE "all zeros"





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/04/19
Raw View
Stephane.Riviere@imag.fr (Stephane Riviere) writes:

>You just have to put your bool definition in an header file protected from
>multiple inclusion, that is for example :
>bool.h :
>
>#ifndef _BOOL_H_
>#define _BOOL_H_

That is a bad example, since the name `_BOOL_H_' (like others starting
with an underscore and an uppercase letter) is reserved for use by the
implementation.  You should use plain `BOOL_H' or, if you must, `BOOL_H_'.

--
Fergus Henderson            | As practiced by computer science, the study of
fjh@cs.mu.oz.au             | programming is an unholy mixture of mathematics,
http://www.cs.mu.oz.au/~fjh | literary criticism, and folklore. - B. A. Sheil





Author: gadget@coho.halcyon.com (Timothy Sharpe)
Date: 1995/04/14
Raw View
>So, I'll propose
>#define TRUE 0
>#define FALSE !TRUE

Correction!!! How silly of me
#define FALSE 0
#define TRUE !FALSE

now functions it doesn't break every existing function return based on
bool values.







Author: johnw@jove.acs.unt.edu (John Robert Williams)
Date: 1995/04/15
Raw View
Timothy Sharpe (gadget@coho.halcyon.com) wrote:
> As such, I do not like the prevailing thread which uses an enum in which
> true is 0 and false is 1.

> So, I'll propose
> #define TRUE 1
> #define FALSE !TRUE

> which might translate to
> const int TRUE = 1;
> const int FALSE = !TRUE;

Why not const TRUE = 0 == 0, false = 0 != 0? or const TRUE = 1 == 1,
FALSE = 0 == 1?

This is harmless but useless. Since if(0) in some form is the only
condition where the statements are not executed, this means that false
MUST be 0. Any other definition is misleading and most likely very stupid.

John Williams
johnw@jove.acs.unt.edu
"Life is case sensitive."






Author: gadget@coho.halcyon.com (Timothy Sharpe)
Date: 1995/04/14
Raw View
I think the bool portibility problem goes back to how systems define
FALSE.

I have seen FALSE defined as: 1, -1, !TRUE, !0

I think this goes back to the fundamental definition of FALSE as "not
equal to true" which has evolved to implementations in which TRUE != !FALSE
which I consider extremely annoying.

As such, I do not like the prevailing thread which uses an enum in which
true is 0 and false is 1.

So, I'll propose
#define TRUE 0
#define FALSE !TRUE

which might translate to
const int TRUE = 0;
const int FALSE = !TRUE;

Tim





Author: andys@thone.demon.co.uk (Andy Sawyer)
Date: 1995/04/12
Raw View
In article <3mfp0m$qkp@giga.bga.com> jamshid@ses.com "Jamshid Afshar" writes:

> In any other situation I would agree (see CPL2 on macros), but since
> bool, true, and false are keywords the normal reasons not to use
> macros (gross scoping, they define their own "little language", they
> cause problems with other C++ tools) aren't as applicable.  In this
> case you *do* want to get errors when some function happens to use the
> name as a local variable or parameter.
>
>         #ifdef LACKS_BOOL  // define this for archaic C++ compilers
>         #define bool int
>         #define true 1
>         #define false 0
>         #endif
>
> Jamshid Afshar
> jamshid@ses.com
>

 If you want to get *errors* when these keywords are used in 'old' code,
I would suggest using some syntactic nonsense in these macros, e.g.

#ifdef LACKS_BOOL
#define bool @@ AARRGGHH it's a bool  @@
#define true @@ AARRGGHH it's a true  @@
#define false @@ AARRGGHH it's a false @@
#endif

This will highlight the use of these keywords fairly quickly...and, of
course, you can extend this to spot use of all the other new keywords.


Regards,
 Andy
--
* Andy Sawyer ** e-mail:andys@thone.demon.co.uk ** Compu$erve:100432,1713 **
 The opinions expressed above are my own, but you are granted the right to
 use and freely distribute them. I accept no responsibility for any injury,
 harm or damage arising from their use.                --   The Management.





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/04/11
Raw View
In article 5u7@hermes.unt.edu, johnw@jove.acs.unt.edu (John Robert Williams) writes:
>Steve Clamage (clamage@Eng.Sun.COM) wrote:
>> johnw@jove.acs.unt.edu (John Robert Williams) writes:
>
>> >It seems that people hare have forgotten about #define!
>
>> I haven't forgotten about #define. Macros are dangerous, and I prefer
>> not to use them. They are hardly ever necessary in C++, and when they
>> are not necessary, better alternatives are usually available.
>
>What's so "dangerous" about #defines? By this statement do you mean that
>#defines are evil and should never be used?

I mean exactly what I said above.

Why are macros dangerous?

1. Macros don't obey scope rules. A macro buried in a nested include file
that you are not even aware of can change the meaning of your program. If
you are lucky, your program won't compile, and you can track down why. If
you are not so lucky, your program merely has incorrect behavior.

2. Macros do textual substitution, not logical substitution, and require
great care to avoid generating syntactically legal but unintended code.

3. Function-like macros do not behave like functions, and can (again)
result in syntactically legal programs with unintended results.

The "danger" in these cases is that you typically get no help at all from
the compiler. Your program is just wrong, in ways which may or may not show
up in testing. When errors do show up, incorrect macro use is hard to find.

If you use const values and inline functions to replace most macro uses, you
have none of these pitfalls. Scope is honored, you get logical substitution
and function semantics. You do not get unexpected semantics if your program
compiles without complaint.


>> >enum _bool {_false,_true};
>> >#define bool  _bool
>> >#define false _false
>> >#define true  _true
>
>> >This will always work.
>
>> It depends on what you mean by "work". If you use this set of definitions
>> with a compiler that supports bool, you change the semantics of the
>> program. You can change a correct program using bool into one which
>> does not compile. You run the risk of having different definitions
>
>So don't use this in programs that need the real bool type!

But you said "This will always work." I pointed out that is not so.

>The whole
>point was to make a program that works on many compilers with no
>modifications. This way the keyword bool is NEVER used, so you don't have
>to worry about semantics changing.

If that's what you want, you should use
 enum Bool { False, True }; // or some variant spelling

This solution has no macros, has the same good properties as your solution,
and does not redefine keywords so as to mislead the reader or maintainer of
the program.

Further, you have not addressed the danger I pointed out. If you neglect to
include the header containing these definitions and compile code on a compiler
that supports bool, your code will compile but have different semantics.

Even worse, if some modules include the definitions and others don't, different
parts of the program may have different ideas about the size of type 'bool'.

With my modified example, code will not compile unless you include the
definitions. Given the choice between discovering errors at compile time
and discovering them during debugging (or after the airplane has crashed),
I choose compile time.

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







Author: johnw@jove.acs.unt.edu (John Robert Williams)
Date: 1995/04/11
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
> If you use const values and inline functions to replace most macro uses, you
> have none of these pitfalls. Scope is honored, you get logical substitution
> and function semantics. You do not get unexpected semantics if your program
> compiles without complaint.

I'm not advocating obligatory macros, just useful ones.

> >The whole
> >point was to make a program that works on many compilers with no
> >modifications. This way the keyword bool is NEVER used, so you don't have
> >to worry about semantics changing.

> If that's what you want, you should use
>  enum Bool { False, True }; // or some variant spelling

> This solution has no macros, has the same good properties as your solution,
> and does not redefine keywords so as to mislead the reader or maintainer of
> the program.

It can be annoying since there are often competing defnitions of bool (in
windows.h, for instance).

> Further, you have not addressed the danger I pointed out. If you neglect to
> include the header containing these definitions and compile code on a compiler
> that supports bool, your code will compile but have different semantics.

Yes, and if you neglect to inclue <stdio.h> in a C program it won't work
right either. What's new here?

> Even worse, if some modules include the definitions and others don't, different
> parts of the program may have different ideas about the size of type 'bool'.

Use this only for entire programs that you know need to use bool. When
you know you have a bool type, don't include the header.

> With my modified example, code will not compile unless you include the
> definitions. Given the choice between discovering errors at compile time
> and discovering them during debugging (or after the airplane has crashed),
> I choose compile time.

It seems that this is mostly a matter of style. I'm willing to trust
myself not to use bool in a way that it will not work with *both* the
enum and the keywords. I think now maybe it's time for this thread to
die, since the original question was answered several times already.

John Williams





Author: raghav@regulus.cs.binghamton.edu (_)
Date: 1995/04/11
Raw View
The #define bool thing was done to death a long time back
why it doesn work is because it doesnt guarantee things like
!false == true
etc.





Author: jamshid@ses.com (Jamshid Afshar)
Date: 1995/04/12
Raw View
In article <3m9153$c99@hermes.unt.edu>,
John Robert Williams <johnw@jove.acs.unt.edu> wrote:
>>For now, the only portable solution is precisely *not* to use bool [...]
>
>It seems that people hare have forgotten about #define!
>
>enum _bool {_false,_true};
>#define bool  _bool
>#define false _false
>#define true  _true
>
>This will always work.

No it won't, at least nowhere near the way a C++ programmer would
expect "bool" to work:

 bool test( int j ) {
    int i;
    /*...calculate i...*/
    return i<j;  // error if bool is an enum
 }

(granted, defining bool as an int does not allow you to overload
 based on it as you can with an enum or the real "bool")

Your code also won't work if you link to a pre-compiled library which
independently decides whether the compiler implements bool.  If your
#define's get seen in a header before the library's headers, you'll
get link-time errors because the library's functions were declared
with your _bool enum, but are defined with the built-in bool.  So, you
still have to surround your #define's with some sort of #if depending
on whether the compiler implements the real "bool".

Jamshid Afshar
jamshid@ses.com





Author: jamshid@ses.com (Jamshid Afshar)
Date: 1995/04/12
Raw View
In article <3m9adu$s1p@ixnews3.ix.netcom.com>,
Cade Roux <cade@ix.netcom.com> wrote:
>In <3m9153$c99@hermes.unt.edu> johnw@jove.acs.unt.edu (John Robert Williams)
>writes:
>>It seems that people hare have forgotten about #define!
>>
>Oh, but shirley, "#define" is left over from C, it's the source of all evil,
>we must get rid of the old ways ;-)

In any other situation I would agree (see CPL2 on macros), but since
bool, true, and false are keywords the normal reasons not to use
macros (gross scoping, they define their own "little language", they
cause problems with other C++ tools) aren't as applicable.  In this
case you *do* want to get errors when some function happens to use the
name as a local variable or parameter.

 #ifdef LACKS_BOOL  // define this for archaic C++ compilers
 #define bool int
 #define true 1
 #define false 0
 #endif

Jamshid Afshar
jamshid@ses.com





Author: johnw@jove.acs.unt.edu (John Robert Williams)
Date: 1995/04/09
Raw View
Cedric Beust (beust@maki.inria.fr) wrote:
> In article <3m126a$rec@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:

> : When you get a compiler that supports bool, remove the definitions from
> : your header file and you don't have to change any code.

>       This is fine as long as you are stuck with one compiler. What if
>       you have portability issues to consider, and are using compilers
>       that define bool, and others that don't ?

>       Is there some kind of standard define that informs me whether
>       the compiler I am using has bool built-in or not ? (I am aware
>       that this question is more compiler-oriented than
>       C++-oriented...)

>       For now, the only portable solution is precisely *not* to use
>       bool, and define my own PersonalBool type, which I'm sure I will
>       find on none of the compilers I am using...

It seems that people hare have forgotten about #define!

enum _bool {_false,_true};
#define bool  _bool
#define false _false
#define true  _true

This will always work.

John Williams
johnw@jove.acs.unt.edu
"Life is case sensitive."






Author: cade@ix.netcom.com (Cade Roux)
Date: 1995/04/09
Raw View
In <3m9153$c99@hermes.unt.edu> johnw@jove.acs.unt.edu (John Robert Williams)
writes:

>
>It seems that people hare have forgotten about #define!
>

Oh, but shirley, "#define" is left over from C, it's the source of all evil, we
must get rid of the old ways ;-)

--
| Cade Roux
| New Orleans, LA -- 73733.1014@compuserve.com -- cade@ix.netcom.com





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/04/10
Raw View
johnw@jove.acs.unt.edu (John Robert Williams) writes:

>It seems that people hare have forgotten about #define!

I haven't forgotten about #define. Macros are dangerous, and I prefer
not to use them. They are hardly ever necessary in C++, and when they
are not necessary, better alternatives are usually available.

>enum _bool {_false,_true};
>#define bool  _bool
>#define false _false
>#define true  _true

>This will always work.

It depends on what you mean by "work". If you use this set of definitions
with a compiler that supports bool, you change the semantics of the
program. You can change a correct program using bool into one which
does not compile. You run the risk of having different definitions
for "bool", "true" and "false" in different program parts, which
is a recipe for subtle and hard-to-find bugs.

You are much better off using a scheme that will reliably result in
compiler error messages when you do something wrong.
--
Steve Clamage, stephen.clamage@eng.sun.com





Author: Stephane.Riviere@imag.fr (Stephane Riviere)
Date: 1995/04/10
Raw View
In article <3m9153$c99@hermes.unt.edu>, johnw@jove.acs.unt.edu (John Robert Williams) writes:
|> Cedric Beust (beust@maki.inria.fr) wrote:
|> > In article <3m126a$rec@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:
|>
|> > : When you get a compiler that supports bool, remove the definitions from
|> > : your header file and you don't have to change any code.
|>
|> >       This is fine as long as you are stuck with one compiler. What if
|> >       you have portability issues to consider, and are using compilers
|> >       that define bool, and others that don't ?
|>

You just have to put your bool definition in an header file protected from
multiple inclusion, that is for example :
bool.h :

#ifndef _BOOL_H_
#define _BOOL_H_
typedef int bool;
cont int false = 0;
const int true = !false;
#endif

Then you #include"bool.h" in the files where you use bool.
If you use a compiler that define bool, then add the flag -D_BOOL_H_ to the
compiler command, and bool.h will not be included.
If think it is more convenient to change the compiler flags in a Makefile,
than to change it in sources files with a lot of
#ifdef ONE_COMPILER .. #elsif OTHERCOMPILER ..

-----------------------------------------------------------------------
-  Stephane.Riviere@imag.fr      |  So watch the old world melt away  -
-                                |  A loss regrets could never mend   -
-  iMAGIS-IMAG                   |  You never miss it till it's gone  -
-  BP 53                         |  So say goodbye say goodbye        -
-  38041 GRENOBLE CEDEX 09       |      Marillion _Season's End_      -
-----------------------------------------------------------------------
-  http://w3imagis.imag.fr/~Stephane.Riviere                          -
-----------------------------------------------------------------------





Author: johnw@jove.acs.unt.edu (John Robert Williams)
Date: 1995/04/11
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
> johnw@jove.acs.unt.edu (John Robert Williams) writes:

> >It seems that people hare have forgotten about #define!

> I haven't forgotten about #define. Macros are dangerous, and I prefer
> not to use them. They are hardly ever necessary in C++, and when they
> are not necessary, better alternatives are usually available.

What's so "dangerous" about #defines? By this statement do you mean that
#defines are evil and should never be used? I've seen plenty of
legitimate uses that cannot be implemented any other way without a great
deal of trouble.

> >enum _bool {_false,_true};
> >#define bool  _bool
> >#define false _false
> >#define true  _true

> >This will always work.

> It depends on what you mean by "work". If you use this set of definitions
> with a compiler that supports bool, you change the semantics of the
> program. You can change a correct program using bool into one which
> does not compile. You run the risk of having different definitions

So don't use this in programs that need the real bool type! The whole
point was to make a program that works on many compilers with no
modifications. This way the keyword bool is NEVER used, so you don't have
to worry about semantics changing.

John Williams
johnw@jove.acs.unt.edu
"Life is case sensitive."






Author: hswu@teleport.com
Date: 1995/04/11
Raw View
In <BEUST.95Apr7105156@maki.inria.fr>, beust@maki.inria.fr (Cedric Beust) writes:
>
>      Is there some kind of standard define that informs me whether
>      the compiler I am using has bool built-in or not ? (I am aware
>      that this question is more compiler-oriented than
>      C++-oriented...)
>

I agree that there should be a standard type ( or at least a class ) of bool. We
use C too long that we think it's the way to use int as bool. It might be convient
for compilers and machine, but conceptually, bool is a type which has two
enumerations "true" and "false", and a set of logic operators. It's not integer.
It doesn't make sence at all to write:
 int i = true;  bool b = i * false;






Author: beust@maki.inria.fr (Cedric Beust)
Date: 1995/04/07
Raw View
In article <3m126a$rec@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve Clamage) writes:

: When you get a compiler that supports bool, remove the definitions from
: your header file and you don't have to change any code.

      This is fine as long as you are stuck with one compiler. What if
      you have portability issues to consider, and are using compilers
      that define bool, and others that don't ?

      Is there some kind of standard define that informs me whether
      the compiler I am using has bool built-in or not ? (I am aware
      that this question is more compiler-oriented than
      C++-oriented...)

      For now, the only portable solution is precisely *not* to use
      bool, and define my own PersonalBool type, which I'm sure I will
      find on none of the compilers I am using...

--
Cedric BEUST, Bull Research Koala project
click <A HREF="http://www.inria.fr/koala/beust.html">here</A>