pll: who uses _Bool

C

Charlie Gordon

Keith Thompson said:
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.

Close, but no cigar ;-)

On those obsolete museum pieces, in the case you describe, a^b would be -0,
a value that compares equal to 0, so the result is correct. But you are
just off by a little: if a=1 and b=-1, a^b yields -0 as well, which of
course is a problem.
The language has a built-in != operator. Just use it. Don't
micro-optimize unless it's absolutely necessary.

Absolutely!
 
T

Tor Rustad

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

Ooops. I had just finished porting the latest splint package, and was
posting at 4 AM, instead of going to bed.
What you probably want is

#if __STDC_VERSION__ >= 199901L
Yes

#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.)

One such relevant case, could be GNU GCC. However, I haven't even
started using "gcc -std=c99 ..." yet, and don't see any problems with
avoiding <stdbool.h>, as long as GCC is C99 non-conforming.

The main advantage of using lowercase bool/true/false, would really be
getting syntax coloring in editors. :)
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.

Well, I don't expect any problems in my existing code, which for
production quality, typically is lint clean.
 
C

Charlie Gordon

Keith Thompson said:
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.

When you do that, do not invoke cygwin's setup from bash: it breaks the
whole distribution, crashes setup, and even rebooting as documented does not
fix it. Cygwin setup keeps crashing. To fix the problem you need to edit
the file c:/cygwin/etc/setup/installed.db and remove the line that starts
with 'bash '.

This is OT, but I just wasted 30 minutes on this crap.
 
T

Tor Rustad

CBFalconer said:
Tor Rustad wrote:
[..]
#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.

Really? Why is using typeless macros under C89 bullet-proof???

Macros doesn't strike me as a good alternative for C89, shutting down
type checking... rarely is a good advice.
 
B

Ben Bacarisse

Charlie Gordon said:
Keith Thompson said:
Ark Khasin said:
Keith Thompson wrote:
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)''.
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.

Close, but no cigar ;-)

On those obsolete museum pieces, in the case you describe, a^b would
be -0, a value that compares equal to 0, so the result is correct.

Not always. An implementation is allowed to "not support negative
zero" and, on these implementations, ^ operations that produce -0
constitute undefined behaviour. Even on two's compliment machines,
sign bit 1 and all value bits 0 is allowed to be a trap
representation.
Absolutely!

I can only add another voice to the this call. Compare values with
operations that deal with values, not ones that deal in
representations.
 
I

Ian Collins

Army1987 said:
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.
Why? I'd have thought the opposite would be true. Why would an
implementation use anything other than sizeof(int) for the size of an
enum (unless an implementation specific pragma were used)?
 
B

Ben Pfaff

Ian Collins said:
Why would an implementation use anything other than sizeof(int)
for the size of an enum (unless an implementation specific
pragma were used)?

To save memory?
 
F

Flash Gordon

Ian Collins wrote, On 28/10/07 19:01:
Why? I'd have thought the opposite would be true. Why would an
implementation use anything other than sizeof(int) for the size of an
enum (unless an implementation specific pragma were used)?

Something other than an int might be used because it was more efficient.
For example, on an 8 bit processor an 8 bit type is likely to be far
more efficient.
 
C

Charlie Gordon

Tor Rustad said:
CBFalconer said:
Tor Rustad wrote:
[..]
#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.

Really? Why is using typeless macros under C89 bullet-proof???

Macros doesn't strike me as a good alternative for C89, shutting down type
checking... rarely is a good advice.

Use this:

#undef bool
typedef enum {false, true} bool;
#define false ((bool)+0)
#define true ((bool)+1)

Have the best of both worlds: the enum for type definition and debugging,
the macros for preprocessing, but that expand to a typed constant.
 
C

Charlie Gordon

Ben Bacarisse said:
Charlie Gordon said:
Keith Thompson said:
Keith Thompson wrote:
[...]
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)''.
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.

Close, but no cigar ;-)

On those obsolete museum pieces, in the case you describe, a^b would
be -0, a value that compares equal to 0, so the result is correct.

Not always. An implementation is allowed to "not support negative
zero" and, on these implementations, ^ operations that produce -0
constitute undefined behaviour. Even on two's compliment machines,
sign bit 1 and all value bits 0 is allowed to be a trap
representation.

Jinx! there is always one more bug ;-)
I can only add another voice to the this call. Compare values with
operations that deal with values, not ones that deal in
representations.

And if you so concerned with efficiency, you can tell the compiler to
optimize with the !! operator:

int cmpneq(int a, int b) { return !!(a != b); }

Or in the VC world:

int cmpneq(int a, int b) { return ("opt:/O2/NODRMCHECK", a != b); }
 
I

Ian Collins

Ben said:
To save memory?

OK, but I wouldn't expect it as a default. On the random samples of 32
and 64 bit machines I've tried, the following prints "1 4".

#include <stdbool.h>
#include <stdio.h>

typedef enum {efalse, etrue} ebool;

int main() {
printf( "%d %d\n", sizeof(bool), sizeof(ebool) );
}


I hit a problem with this last week, someone was integrating some C code
into a C++ test harness and wondered why they were seeing garbage values
when reading back members of a struct that had a bool member. The C
compiler saw the enum definition in the header and used 4 for
sizeof(bool), the C++ compiler just used built in bool with 1 as
sizeof(bool).
 
I

Ian Collins

Flash said:
Ian Collins wrote, On 28/10/07 19:01:

Something other than an int might be used because it was more efficient.
For example, on an 8 bit processor an 8 bit type is likely to be far
more efficient.

Maybe, *might* be used I agree with, I was questioning "in particular
I'd *expect* sizeof (_Bool) to equal sizeof (enum {false, true}) on most
of implementations having _Bool".
 
C

CBFalconer

Tor said:
CBFalconer said:
Tor Rustad wrote:
[..]
#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.

Really? Why is using typeless macros under C89 bullet-proof???

Macros doesn't strike me as a good alternative for C89, shutting
down type checking... rarely is a good advice.

Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.
 
A

Ark Khasin

Ben said:
Charlie Gordon said:
Keith Thompson said:
Keith Thompson wrote:
[...]
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)''.
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.
Close, but no cigar ;-)

On those obsolete museum pieces, in the case you describe, a^b would
be -0, a value that compares equal to 0, so the result is correct.

Not always. An implementation is allowed to "not support negative
zero" and, on these implementations, ^ operations that produce -0
constitute undefined behaviour. Even on two's compliment machines,
sign bit 1 and all value bits 0 is allowed to be a trap
representation.
Absolutely!

I can only add another voice to the this call. Compare values with
operations that deal with values, not ones that deal in
representations.
To all who responded to my last post above:
OK, you proved me a _Fool with implementation of cmpneq.

But my point remains: unless the compiler can optimize the _correct_
cmneq by inlining it, there is (almost certainly) a performance hit.
Thus, bool better go hand in hand with (static) inline.

As to whether or not optimize the primitives to death - opinions vary
but why use C if I don't have to care?
 
T

Tor Rustad

CBFalconer said:
Tor said:
CBFalconer said:
Tor Rustad wrote: [..]

#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.
Really? Why is using typeless macros under C89 bullet-proof???

Macros doesn't strike me as a good alternative for C89, shutting
down type checking... rarely is a good advice.

Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.

Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

?

Why this the above *better* under C89, than using

typedef enum {false, true} bool;

?
 
C

Charlie Gordon

Tor Rustad said:
CBFalconer said:
Tor said:
CBFalconer wrote:
Tor Rustad wrote:
[..]

#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.
Really? Why is using typeless macros under C89 bullet-proof???

Macros doesn't strike me as a good alternative for C89, shutting
down type checking... rarely is a good advice.

Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.

Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

true and false will expand to int constants.
Why this the above *better* under C89, than using

typedef enum {false, true} bool;

consider this:

#if true
....
#endif

The standard explicitly allows this, and mandates that true be defined to 1
for that very purpose (7.16p3). with just the enum, #if true ultimately
evaluates to #if 0. QED
 
K

Keith Thompson

Charlie Gordon said:
"Tor Rustad" <[email protected]> a écrit dans le message de
(e-mail address removed)... [...]
Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

true and false will expand to int constants.
Why this the above *better* under C89, than using

typedef enum {false, true} bool;

consider this:

#if true
...
#endif

The standard explicitly allows this, and mandates that true be defined to 1
for that very purpose (7.16p3). with just the enum, #if true ultimately
evaluates to #if 0. QED

It's just not possible to completely reproduce the semantics of C99's
_Bool and <stdbool.h> in C90. You can write code that reproduces most
of the *useful* semantics, such as:

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

and then just use them normally, but avoid any trickery like expecting
conversions to bool to work as they do in C99.
 
C

CBFalconer

Tor said:
CBFalconer wrote:
.... snip ...
Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.

Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

The macro has nothing to do with type. Wherever the id 'true'
appears, it will be replaced by the id '1'. Similarly for 'false'
and '0'. Any type checking depends entirely on the use of those
ids (0 and 1) in the resultant expression.

For example, the expression sequence:

size_t st;
...
st = -true;

whill result in st setting to SIZE_T_MAX, whatever that may be.
 
K

Keith Thompson

CBFalconer said:
Tor said:
CBFalconer wrote: ... snip ...
Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.

Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

The macro has nothing to do with type. Wherever the id 'true'
appears, it will be replaced by the id '1'. Similarly for 'false'
and '0'. Any type checking depends entirely on the use of those
ids (0 and 1) in the resultant expression.

``true'' and ``false'' are identifers (I presume that's what you mean
by "id"); ``0'' and ``1'' are not. Yes, I'm nitpicking, but correct
terminology is important.
For example, the expression sequence:

size_t st;
...
st = -true;

whill result in st setting to SIZE_T_MAX, whatever that may be.

Yes, but that's not relevant to the type of ``true''.

``true'' expands to the integer constant ``1'', which is of type int,
regardless of the context in which it appears. (In some contexts, it
may then be implicitly converted to some other type.)
 
C

CBFalconer

Keith said:
CBFalconer said:
Tor said:
CBFalconer wrote:

... snip ...
Macros don't shut down type checking. They do text replacement,
and the resultant expression gets as type-checked as the compiler
is capable of.

Now, what is the type of true and false, when using:

$ cat /usr/lib/gcc/i486-linux-gnu/4.1.2/include/stdbool.h
[...]
#define true 1
#define false 0

The macro has nothing to do with type. Wherever the id 'true'
appears, it will be replaced by the id '1'. Similarly for 'false'
and '0'. Any type checking depends entirely on the use of those
ids (0 and 1) in the resultant expression.

``true'' and ``false'' are identifers (I presume that's what you
mean by "id"); ``0'' and ``1'' are not. Yes, I'm nitpicking, but
correct terminology is important.
For example, the expression sequence:

size_t st;
...
st = -true;

whill result in st setting to SIZE_T_MAX, whatever that may be.

Yes, but that's not relevant to the type of ``true''.

``true'' expands to the integer constant ``1'', which is of type
int, regardless of the context in which it appears. (In some
contexts, it may then be implicitly converted to some other type.)

I disagree. I can affect the macro expansion with the '#'
operation. This can change the "1" resulting from the macro
expansion to, say, 1u. No change to the macro is required. The
primary thing that happens is the '1' appears in the code. I can
even envelop that alteration in further ridiculous macros.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top