pll: who uses _Bool

S

Szabolcs Nagy

who has used _Bool? (or included stdbool.h for bool, true, false?)

(i'm considering using it in a library for home projects)
 
M

Malcolm McLean

Szabolcs Nagy said:
who has used _Bool? (or included stdbool.h for bool, true, false?)

(i'm considering using it in a library for home projects)
Here's what Dennis Ritchie has to say about it

"Of the new things, restricted pointers probably are a help; variadic macros
and bool are just adornment. I've heard the argument for complex numbers for
a long time, and maybe it was inevitable, but it does somewhat increase the
cross-product of the type rules and inflate the library. One issue the
question didn't mention is the introduction of the "long long" type and its
implications, which is one of the more contentious issues in discussion
groups about the language -- and it also makes the type-promotion rules much
more complicated. But of course, 64-bit machines and storage are here, and
it had to be faced."
http://www.itworld.com/Comp/3380/lw-12-ritchie/

use bool not _Bool, though. Bool breaks libraries.
 
T

Tor Rustad

Szabolcs said:
who has used _Bool? (or included stdbool.h for bool, true, false?)

(i'm considering using it in a library for home projects)

Since <stdbool.h> isn't available on all the relevant compilers, I stil
roll my own boolean definitions. I should perhaps switch to lower-case
now, using something ala:

#ifdef __STDC_IEC_559__
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif
 
A

Ark Khasin

Szabolcs said:
who has used _Bool? (or included stdbool.h for bool, true, false?)

(i'm considering using it in a library for home projects)
IMHO, bool (or _Bool) goes hand in hand with static inline (and an
optimizing compiler). Otherwise, you will immediately pay performance
and code size penalties for syntactic sugar, and if you don't have to
care, C might not be the right language for your project.
I mean, types aside, semantic Booleans are not free:
int cmpneq(int a, int b) {return a!=b;}
is less efficient than
int cmpneq(int a, int b) {return a-b;}
 
K

Keith Thompson

Tor Rustad said:
Since <stdbool.h> isn't available on all the relevant compilers, I
stil roll my own boolean definitions. I should perhaps switch to
lower-case now, using something ala:

#ifdef __STDC_IEC_559__
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif

__STDC_IEC_559__ tells you whether the implementation conforms to the
IEC 60559 floating-point standard.

What you probably want is

#if __STDC_VERSION__ >= 199901L
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif

But note that an implementation might provide <stdbool.h> without
fully conforming to C99 or having __STDC_VERSION__ >= 199901L. An
alternative is to use mechanisms outside the language to test during
configuration whether <stdbool.h> exists. (But occasionally using the
enum when <stdbool.h> is available isn't a big problem.)

You also have to be a bit careful with the code that uses ``bool'';
the enum type doesn't fully capture the semantics of C99's _Bool.
 
K

Keith Thompson

Ark Khasin said:
IMHO, bool (or _Bool) goes hand in hand with static inline (and an
optimizing compiler). Otherwise, you will immediately pay performance
and code size penalties for syntactic sugar, and if you don't have to
care, C might not be the right language for your project.
I mean, types aside, semantic Booleans are not free:
int cmpneq(int a, int b) {return a!=b;}
is less efficient than
int cmpneq(int a, int b) {return a-b;}

The first has the considerable advantage of being correct. The
``a-b'' version exhibits undefined behavior on overflow. Consider
``cmpneq(INT_MIN, INT_MAX)''.

And how do you know that ``a!=b'' is less efficient than ``a-b''?
Have you measured it? Depending on the architecture, it's possible
that each could compile to a single instruction.
 
B

Ben Pfaff

Tor Rustad said:
Since <stdbool.h> isn't available on all the relevant compilers, I
stil roll my own boolean definitions. I should perhaps switch to
lower-case now, using something ala:

#ifdef __STDC_IEC_559__
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif

For what it's worth, the standard says that true, false, and bool
are macros, not enumerations or typedef names. (Not that this
will often make a difference in practice.)
 
C

CBFalconer

Tor said:
Since <stdbool.h> isn't available on all the relevant compilers, I
stil roll my own boolean definitions. I should perhaps switch to
lower-case now, using something ala:

#ifdef __STDC_IEC_559__
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif

I suggest that whenever you do so, you duplicate exactly the
statements (or a subset of them) that you find in stdbool.h. Read
the c standard to discover what they are. Of course _Bool will not
exist. That way you won't run into trouble when the system is
compiled under C99 up.
 
A

Ark Khasin

Keith said:
The first has the considerable advantage of being correct. The
``a-b'' version exhibits undefined behavior on overflow. Consider
``cmpneq(INT_MIN, INT_MAX)''.
Sorry. I ought to be more careful. Here is a repaired version:
int cmpneq(int a, int b) {return a^b;}
As a practical matter though, I've always seen a-b+b yielding a and thus
a-b didn't evaluate to 0. I know it's a meek defense in this ng. :)
And how do you know that ``a!=b'' is less efficient than ``a-b''?
Have you measured it? Depending on the architecture, it's possible
that each could compile to a single instruction.
I may have limited exposure, but I've never seen an instruction set that
would invent a 1 or 0 out of non-equal or equal a and b in a single
instruction. Every instruction set I've seen can invent a non-0 or a 0
out of non-equal or equal a and b in a single instruction [common
disclaimers on sizeof(int) vs. register size apply].
It's likely that a Boolean version can _never_ be more efficient than
the integer one, and in most cases is less efficient.
 
C

Chris Torek

I may have limited exposure, but I've never seen an instruction set that
would invent a 1 or 0 out of non-equal or equal a and b in a single
instruction.

MIPS architecture:

setne t0,a,b /* assuming a and b are in registers */

(In fact, if you want to *test* whether a != b, you have to use a
setne instruction to set a register to 1 or 0, followed by a branch
on register value instruction. I am not sure whether t0 is a
conventional target register for this; the "t", "v", and "a"
registers are the most likely candidates though.)
Every instruction set I've seen can invent a non-0 or a 0
out of non-equal or equal a and b in a single instruction [common
disclaimers on sizeof(int) vs. register size apply].

Yes, most can do this with subtract or exclusive-or (or both),
including MIPS. However, care must be used with subtract, lest
one get an integer-overflow exception (on MIPS this means using
the "unsigned" instructions, on x86 it means using xor or making
sure you never set the trap bit, on SPARC it means not adding a
"trap on condition codes" instruction, etc.).
It's likely that a Boolean version can _never_ be more efficient than
the integer one, and in most cases is less efficient.

This is why compilers optimize. :)
 
I

Ian Collins

Ark said:
It's likely that a Boolean version can _never_ be more efficient than
the integer one, and in most cases is less efficient.
In the cases where any difference in efficiency would be noticed, the
function is probably trivial enough to be inlined away.
 
M

Malcolm McLean

Tor Rustad said:
Since <stdbool.h> isn't available on all the relevant compilers, I stil
roll my own boolean definitions. I should perhaps switch to lower-case
now, using something ala:

#ifdef __STDC_IEC_559__
#include <stdbool.h>
#else
typedef enum {false, true} bool;
#endif
This is the same mistake as

#define start {

but a little bit more subtle.
 
C

cr88192

Szabolcs Nagy said:
who has used _Bool? (or included stdbool.h for bool, true, false?)

(i'm considering using it in a library for home projects)

personally, I don't see any real advantage of _Bool, apart from the vague
possibility of it serving as a programmer hint...
and, it is ugly...


so, C99:
some features are useful (complex and long long, for example);
some features just add complexity (dynamic arrays, ...);
some features are, IMO, frivolous...

and, worse in the case of bool: it is not present...
the version of mingw I am using lacks stdbool.h...
and, what is more, so does cygwin...

so, if one can convince themselves that it is useful, they then have to find
a compiler that has it...

or something...


now, that is not to stop some people from being like:
#ifndef bool
#define bool int
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif

where I have seen similar in at least a few projects...
 
B

Ben Bacarisse

Ark Khasin said:
Sorry. I ought to be more careful. Here is a repaired version:
int cmpneq(int a, int b) {return a^b;}

There are, I think, some corner cases that make this non-portable.
Even on two's compliment implementations, ^ can result in a trap
representation. My non-authoritative PDF has some change bars here
(6.2.6.2) so this may be a recent clarification.
 
A

Army1987

For what it's worth, the standard says that true, false, and bool
are macros, not enumerations or typedef names. (Not that this
will often make a difference in practice.)
Well, #if true will do the wrong thing... But I can't think of
any other difference. But using macros, the most reasonable choice
for bool in C89 is int, whereas with an enum an implementation is
allowed to choose a smaller type if it thinks it is equally (or
more) efficient, in particular I'd expect sizeof (_Bool) to equal
sizeof (enum {false, true}) on most of implementations having
_Bool.
 
E

Eric Sosman

Ben said:
For what it's worth, the standard says that true, false, and bool
are macros, not enumerations or typedef names. (Not that this
will often make a difference in practice.)

Notice that the definition above is not quite equivalent
to C99's bool. Here's a way to see the difference:

bool b;
b = 42;
if (b == 1)
puts ("C99-style bool");
else
puts ("Trickery is rampant");

That is, converting *any* non-zero value to C99 bool produces
the value `(bool)1'.
 
C

Charlie Gordon

Eric Sosman said:
Notice that the definition above is not quite equivalent
to C99's bool. Here's a way to see the difference:

bool b;
b = 42;
if (b == 1)
puts ("C99-style bool");
else
puts ("Trickery is rampant");

That is, converting *any* non-zero value to C99 bool produces
the value `(bool)1'.

Does it convert NaNs to true ?
 
E

Eric Sosman

Charlie said:
Does it convert NaNs to true ?

Yes. 6.3.1.2:

"When any scalar value is converted to _Bool,
the result is 0 if the value compares equal
to 0; otherwise, the result is 1."

Since NaN does not compare equal to 0, the conversion yields 1.
 
K

Keith Thompson

Ark Khasin said:
Sorry. I ought to be more careful. Here is a repaired version:
int cmpneq(int a, int b) {return a^b;}
[...]

Bitwise operations on signed types always make me nervous.

In this case, for an implementation that uses ones'-complement or
sign-and-magnitude, a^b will fail if a is +0 and b is -0.

The language has a built-in != operator. Just use it. Don't
micro-optimize unless it's absolutely necessary.
 
K

Keith Thompson

cr88192 said:
and, worse in the case of bool: it is not present...
the version of mingw I am using lacks stdbool.h...
and, what is more, so does cygwin...
[...]

Cygwin does provide <stdbool.h>. Perhaps you just need to update your
system.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top