Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #93399 > unrolled thread

Why _Bool was not defined as enum in C99?

Started bythiago.adams@gmail.com
First post2016-09-12 13:24 -0700
Last post2016-09-17 17:14 -0700
Articles 20 on this page of 86 — 16 participants

Back to article view | Back to comp.lang.c


Contents

  Why _Bool was not defined as enum in C99? thiago.adams@gmail.com - 2016-09-12 13:24 -0700
    Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-12 21:56 +0100
      Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-12 15:59 -0700
      Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 16:05 -0700
        Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-13 18:17 -0700
          Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-14 01:20 +0100
          Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-14 03:59 -0700
          Re: Why _Bool was not defined as enum in C99? Nobody <nobody@nowhere.invalid> - 2016-09-14 17:31 +0100
            Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 09:49 -0700
              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 11:45 -0700
          Re: Why _Bool was not defined as enum in C99? <william@wilbur.25thandClement.com> - 2016-09-14 14:13 -0700
            Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 16:26 -0700
    Re: Why _Bool was not defined as enum in C99? "James R. Kuyper" <jameskuyper@verizon.net> - 2016-09-12 17:11 -0400
    Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-13 15:55 -0700
      Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-13 18:08 -0700
        Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-14 03:56 -0700
          Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 07:58 -0700
            Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-14 19:39 +0100
              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 13:52 -0700
                Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-15 00:53 +0100
                  Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 17:04 -0700
                    Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 20:52 -0700
                      Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 19:26 -0700
                  Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 19:04 -0700
              Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 14:21 -0700
                Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 16:23 -0700
                  Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 17:06 -0700
                    Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 20:45 -0700
                    Re: Why _Bool was not defined as enum in C99? Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-14 22:12 -0400
                    Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-15 12:37 +0200
                      Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 09:35 -0700
                        Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 00:47 +0200
                          Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 22:02 -0700
                            Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 09:56 +0200
                              Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-16 07:34 -0700
                                Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 20:31 +0200
                                  Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-16 12:32 -0700
                                    Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-17 23:30 +0200
                      Re: Why _Bool was not defined as enum in C99? BartC <bc@freeuk.com> - 2016-09-15 18:25 +0100
                        Re: Why _Bool was not defined as enum in C99? luser droog <luser.droog@gmail.com> - 2016-09-15 12:35 -0700
                          Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 00:51 +0200
                            Re: Why _Bool was not defined as enum in C99? luser droog <luser.droog@gmail.com> - 2016-09-16 17:02 -0700
                              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-16 19:23 -0700
                              Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-17 23:35 +0200
          Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 10:40 -0700
            Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-14 10:01 -0700
              Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 11:35 -0700
                Re: Why _Bool was not defined as enum in C99? Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-14 22:15 -0400
                  Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-14 23:51 -0700
                    Re: Why _Bool was not defined as enum in C99? Jerry Stuckle <jstucklex@attglobal.net> - 2016-09-15 15:14 -0400
                Re: Why _Bool was not defined as enum in C99? Ian Collins <ian-news@hotmail.com> - 2016-09-15 16:08 +1200
                  Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-15 12:46 +0200
                    Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 09:37 -0700
                      Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 00:53 +0200
                        Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 21:45 -0700
                          Re: Why _Bool was not defined as enum in C99? Richard Heathfield <rjh@cpax.org.uk> - 2016-09-16 06:32 +0100
                            Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 09:59 +0200
                            Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-16 11:00 +0100
                              Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 04:46 -0700
                                Re: Why _Bool was not defined as enum in C99? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-16 12:58 +0100
                                  Re: Why _Bool was not defined as enum in C99? Melzzzzz <Melzzzzz@zzzzz.com> - 2016-09-16 12:06 +0000
                                    Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 05:13 -0700
                                    Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-16 10:47 -0700
                              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-16 10:46 -0700
                          Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 10:02 +0200
                    Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 11:42 -0700
                      Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 10:19 +0200
                        Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-16 08:06 -0700
                          Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 20:51 +0200
                            Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 11:56 -0700
                            Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 22:38 -0700
            Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-14 11:42 -0700
              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-14 14:02 -0700
                Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-15 10:51 -0700
                  Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 11:18 -0700
                    Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-15 13:46 -0700
                      Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-15 13:10 -0700
                        Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-15 16:01 -0700
                  Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-15 13:40 -0700
                    Re: Why _Bool was not defined as enum in C99? Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-16 07:21 -0700
                      Re: Why _Bool was not defined as enum in C99? Thiago Adams <thiago.adams@gmail.com> - 2016-09-16 07:37 -0700
                        Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-16 20:55 +0200
                          Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-16 14:43 -0700
                            Re: Why _Bool was not defined as enum in C99? supercat@casperkitty.com - 2016-09-16 15:36 -0700
                            Re: Why _Bool was not defined as enum in C99? David Brown <david.brown@hesbynett.no> - 2016-09-17 23:45 +0200
                              Re: Why _Bool was not defined as enum in C99? Keith Thompson <kst-u@mib.org> - 2016-09-17 17:14 -0700

Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →


#93509

Fromsupercat@casperkitty.com
Date2016-09-14 17:04 -0700
Message-ID<38dfafa1-1409-46d7-afcf-449ec015886d@googlegroups.com>
In reply to#93507
On Wednesday, September 14, 2016 at 6:53:28 PM UTC-5, Ben Bacarisse wrote:
> But if it's a special enumeration with its own conversion semantics, how
> do you know that is *not* how _Bool is implemented?  Or, to put it
> slightly differently, what would give the game away so you could say
> that it's a special enumerated type with its own semantics?

How do you know it's not a "pointer type", but with a different set of
allowable implicit conversions that differs from those of normal pointer
types?  Using terms as they were defined in C89, _Bool is not an integral
type, and I do not think any useful purpose is served by expanding the
definition of "integral type" to include _Bool rather than regarding it as
a new kind of type which is neither an integral, floating-point, pointer,
function, array, struct, bitfield, enumerated, void, or union type.  The
type _Bool is an integral type only because the authors of the Standard
chose to expand the definition of "integral type", rather than some other
kind of type, to include it.

[toc] | [prev] | [next] | [standalone]


#93516

FromKeith Thompson <kst-u@mib.org>
Date2016-09-14 20:52 -0700
Message-ID<ln1t0l4y6k.fsf@kst-u.example.com>
In reply to#93509
supercat@casperkitty.com writes:
> On Wednesday, September 14, 2016 at 6:53:28 PM UTC-5, Ben Bacarisse wrote:
>> But if it's a special enumeration with its own conversion semantics, how
>> do you know that is *not* how _Bool is implemented?  Or, to put it
>> slightly differently, what would give the game away so you could say
>> that it's a special enumerated type with its own semantics?
>
> How do you know it's not a "pointer type", but with a different set of
> allowable implicit conversions that differs from those of normal pointer
> types?

Um, because you can't dereference it, or perform *any* of the operations
that normally apply to pointers and not to non-pointers?

There are languages in which the boolean type (called bool, or Boolean,
or whatever) *is* an enumeration type, and at least for those languages
it works just fine.  There are exactly two values, specified by the
enumeration constants.

>         Using terms as they were defined in C89, _Bool is not an integral
> type,

Neither is long long.

>       and I do not think any useful purpose is served by expanding the
> definition of "integral type" to include _Bool rather than regarding it as
> a new kind of type which is neither an integral, floating-point, pointer,
> function, array, struct, bitfield, enumerated, void, or union type.  The
> type _Bool is an integral type only because the authors of the Standard
> chose to expand the definition of "integral type", rather than some other
> kind of type, to include it.

The standard would have had to add special rules to deal with this new
kind of type, rather than taking the existing rules for integer types
and tweaking them slightly for _Bool.  Making it anything other than an
enumeration type (struct, void, union) just wouldn't have made any
sense.

Sure, it could have been done as you suggest.  It wasn't.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#93519

Fromsupercat@casperkitty.com
Date2016-09-14 19:26 -0700
Message-ID<39bcacdb-d695-4059-8be6-45013891fca6@googlegroups.com>
In reply to#93516
On Wednesday, September 14, 2016 at 9:01:50 PM UTC-5, Keith Thompson wrote:
> supercat writes:
> >         Using terms as they were defined in C89, _Bool is not an integral
> > type,
> 
> Neither is long long.

If a C89 compiler had a type which behaved like C99's "long long", such
a type would be an "extended integer type" and would be subject to the
rules which are applicable to integral types (e.g. converting 0.1f to such
a type would yield 0 and conversion of a pointer to such a type without
a cast would make a program ill-formed).  

By contrast, if a C89 compiler had a type which behaved like _Bool, there
would be no terminology in C89 to describe how such a type works, but it
would *not* obey the rules associated with integral types.

> The standard would have had to add special rules to deal with this new
> kind of type, rather than taking the existing rules for integer types
> and tweaking them slightly for _Bool.  Making it anything other than an
> enumeration type (struct, void, union) just wouldn't have made any
> sense.

A value of type _Bool is implicitly convertible to an int, and values of
integral types are convertible to _Bool, but I can't think of any other
traits they share with integral types.

[toc] | [prev] | [next] | [standalone]


#93511

FromKeith Thompson <kst-u@mib.org>
Date2016-09-14 19:04 -0700
Message-ID<lna8f95360.fsf@kst-u.example.com>
In reply to#93507
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>> supercat@casperkitty.com writes:
>> [...]
>>>> if the Committee had simply used an enumerated type, the
>>>> semantics of enumerated types would--by definition--have fit
>>>> perfectly.
>>>
>>> You'd have expressions E such that
>>>
>>>   if ((_Bool)E)
>>>
>>> and
>>>
>>>   if (E)
>>>
>>> behave differently.
>>>
>>> <snip>
>>
>> Not if the hypothetical enumerated _Bool has the same conversion
>> semantics as the built-in _Bool that was actually added in C99.
>> I don't think anyone is suggesting just adding the equivalent of
>> a predefined
>>
>>     typedef enum { false, true } _Bool;
>>
>> and leaving it at that.
>
> Actually, I thought that was exactly what the OP was asking about.  And
> it sounds like it is what supercat was talking about in the message I
> replied to.  That's how I read "if the Committee had simply used an
> enumerated type" and the idea that the semantics would be right by
> definition.

Ok, I might have misinterpreted what others were saying.

> But if it's a special enumeration with its own conversion semantics, how
> do you know that is *not* how _Bool is implemented?  Or, to put it
> slightly differently, what would give the game away so you could say
> that it's a special enumerated type with its own semantics?

For the type itself, I can't think of a way to detect the difference.
But you could certainly detect the difference in the way false
and true are defined (assuming that the type name _Bool and the
constants false and true are all predefined by something resembling
an enumerated type definition).

BTW, I've been wondering why bool is defined as a macro rather than
as a typedef.  My best guess is that it's to allow for code that
(a) defines its own "bool" somehow, but (b) indirectly, and probably
unintentionally, includes <stdbool.h>.  If you have some pre-C99 code
that has, for example:

    typedef enum { false, true } bool;

then you can change it to:

    #undef bool
    #undef false
    #undef true
    typedef enum { false, true } bool;

and it will still compile correctly even if <stdbool.h> is present.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#93492

Fromsupercat@casperkitty.com
Date2016-09-14 14:21 -0700
Message-ID<f9f05989-4782-4e78-be33-21778b981e77@googlegroups.com>
In reply to#93469
On Wednesday, September 14, 2016 at 1:40:04 PM UTC-5, Ben Bacarisse wrote:
> supercat writes:
> > I am unaware of any "existing" semantics for _Bool before the Committee
> > invented them;
> 
> Yes, there are.  Obviously not for _Bool itself -- that did not exist --
> but in "if (...)", "while (...)" and as operands of &&, || and ! an
> expression is treated as being Boolean.

Given a statement like "if (somePointer) f();", the value of somePointer
will be compared against null, and if the comparison reports unequal the
function f() will be invoked.  I see nothing in the Standard to imply that
a compiler should be expected to produce something with value 0 if the
pointer compares equal and 1 if it doesn't.  If the code had been written
as "if (somePointer && someFloat) f()", then the code would semantically
produce a 1 if neither value compared equal to its type's "zero" and a
0 otherwise, and then branch based upon the value produced, but the 0 or
1 are produced by the "&&" operator and not be the sub-expressions.

As it is, since the _Bool type will seldom generate better code than
"unsigned char", and will sometimes generate worse code, I'm not quite
clear why programmers should use it except to communicate with APIs that
also do so.

[toc] | [prev] | [next] | [standalone]


#93495

FromKeith Thompson <kst-u@mib.org>
Date2016-09-14 16:23 -0700
Message-ID<lnvaxy3w29.fsf@kst-u.example.com>
In reply to#93492
supercat@casperkitty.com writes:
[...]
> As it is, since the _Bool type will seldom generate better code than
> "unsigned char", and will sometimes generate worse code, I'm not quite
> clear why programmers should use it except to communicate with APIs that
> also do so.

Programmers should use _Bool or bool because it's substantially clearer
than using unsigned char to represent a true/false condition.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#93510

Fromsupercat@casperkitty.com
Date2016-09-14 17:06 -0700
Message-ID<c544ef10-4ba2-4b2a-a36f-ccffb550e3f1@googlegroups.com>
In reply to#93495
On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
> Programmers should use _Bool or bool because it's substantially clearer
> than using unsigned char to represent a true/false condition.

What's the advantage of using a less-efficient type versus a user-defined
"flag" type could allow more efficient code generation?

[toc] | [prev] | [next] | [standalone]


#93515

FromKeith Thompson <kst-u@mib.org>
Date2016-09-14 20:45 -0700
Message-ID<ln60px4yho.fsf@kst-u.example.com>
In reply to#93510
supercat@casperkitty.com writes:
> On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
>> Programmers should use _Bool or bool because it's substantially clearer
>> than using unsigned char to represent a true/false condition.
>
> What's the advantage of using a less-efficient type versus a user-defined
> "flag" type could allow more efficient code generation?

I already answered that.  See above.

If using unsigned char makes the code *significantly* and
*measurably* faster, by all means use it (and perhaps consider
complaining to your compiler vendor).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#93517

FromJerry Stuckle <jstucklex@attglobal.net>
Date2016-09-14 22:12 -0400
Message-ID<nrd01t$jpg$1@jstuckle.eternal-september.org>
In reply to#93510
On 9/14/2016 8:06 PM, supercat@casperkitty.com wrote:
> On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
>> Programmers should use _Bool or bool because it's substantially clearer
>> than using unsigned char to represent a true/false condition.
> 
> What's the advantage of using a less-efficient type versus a user-defined
> "flag" type could allow more efficient code generation?
> 

Clarity supersedes (or should, in good programming) premature
optimization.

Efficiency of code generation should only be a concern when you find the
current code has performance problems.  Otherwise, code clarity is the
primary concern to a good programmer.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================

[toc] | [prev] | [next] | [standalone]


#93528

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-15 12:37 +0200
Message-ID<nrdtlg$un$1@dont-email.me>
In reply to#93510
On 15/09/16 02:06, supercat@casperkitty.com wrote:
> On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
>> Programmers should use _Bool or bool because it's substantially clearer
>> than using unsigned char to represent a true/false condition.
> 
> What's the advantage of using a less-efficient type versus a user-defined
> "flag" type could allow more efficient code generation?
> 

As Keith says, bool is clearer and therefore better.  Clarity is not
necessarily the overriding factor, but it is usually very important.

Remember also that bool has another useful property - any assignment to
a bool variable will give it the value 0 or 1, unless you /really/ go
out of your way to mess things up for yourself (with pointer casts and
the like).  This is a useful feature you can rely on - and the compiler
can rely on it too.

In most cases, with modern tools, bool and an unsigned char will have
the same efficiency for the same job.  bool obviously "wins" in such cases.

In other cases, one of them might be more efficient than the other.  The
only reason to use unsigned char or another user-defined type would be
if you know, for sure, that the other type is more efficient - and that
you know, and have measured, that this difference is significant.

[toc] | [prev] | [next] | [standalone]


#93548

Fromsupercat@casperkitty.com
Date2016-09-15 09:35 -0700
Message-ID<d96aea8f-52de-4481-bd08-e15819a98181@googlegroups.com>
In reply to#93528
On Thursday, September 15, 2016 at 5:37:49 AM UTC-5, David Brown wrote:
> Remember also that bool has another useful property - any assignment to
> a bool variable will give it the value 0 or 1, unless you /really/ go
> out of your way to mess things up for yourself (with pointer casts and
> the like).  This is a useful feature you can rely on - and the compiler
> can rely on it too.

I would regard

   someBool = functionYieldingZeroOrOne();

and

   someBool = functionYieldingOtherValues();

as semantically different, and would suggest that the latter would be more
clearly written as

   someBool = !!functionYieldingOtherValues();

to make clear that the code is expected to convert non-zero values other
than 0 or 1.  Among other things, the first and third forms will work just
fine if someBool is replaced with an integral type, while the second form
won't unless it's rewritten like the third.

In cases where the function will always return 0 or 1 but the compiler
doesn't know that, there's no way to tell the compiler that.  Given how
willing the Committee is to erode the semantics of C in the name of
"optimization", I find it ironic that they they missed some really low
hanging fruit here.

> In most cases, with modern tools, bool and an unsigned char will have
> the same efficiency for the same job.  bool obviously "wins" in such cases.

If an expression which will always yield 0 or 1 is stored into a _Bool, a
compiler will have no choice but to generate unnecessarily inefficient
code unless either:

  1. It can tell that the value will always be 0 or 1

  2. It can tell that all code which examines the value will work just
     fine with anything that the expression could yield (e.g. the
     expression had type "unsigned char", and everything that reads the
     variable tests whether it's non-zero).

[toc] | [prev] | [next] | [standalone]


#93586

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-16 00:47 +0200
Message-ID<nrf8em$pi5$1@dont-email.me>
In reply to#93548
On 15/09/16 18:35, supercat@casperkitty.com wrote:
> On Thursday, September 15, 2016 at 5:37:49 AM UTC-5, David Brown wrote:
>> Remember also that bool has another useful property - any assignment to
>> a bool variable will give it the value 0 or 1, unless you /really/ go
>> out of your way to mess things up for yourself (with pointer casts and
>> the like).  This is a useful feature you can rely on - and the compiler
>> can rely on it too.
>
> I would regard
>
>     someBool = functionYieldingZeroOrOne();
>
> and
>
>     someBool = functionYieldingOtherValues();

The point is, if the function's return type is "bool", then you already 
know it can only return true or false.  You don't need to add it to the 
function's name, or use the !! combination.  And if a function's return 
type is /not/ bool, then you already know it can yield other values - 
but you also know that converting it to a bool will force it to true or 
false.

>
> as semantically different, and would suggest that the latter would be more
> clearly written as
>
>     someBool = !!functionYieldingOtherValues();
>
> to make clear that the code is expected to convert non-zero values other
> than 0 or 1.  Among other things, the first and third forms will work just
> fine if someBool is replaced with an integral type, while the second form
> won't unless it's rewritten like the third.
>
> In cases where the function will always return 0 or 1 but the compiler
> doesn't know that, there's no way to tell the compiler that.  Given how
> willing the Committee is to erode the semantics of C in the name of
> "optimization", I find it ironic that they they missed some really low
> hanging fruit here.

The standards committee has /not/ eroded the semantics of C - /please/ 
stop repeating this claim.

But it would be nice if there were a standardised way to give extra 
information to the compiler for optimisation purposes.  Some compilers 
will let you do it, such as with gcc:

if ((x != 0) && (x != 1)) __builtin_unreachable();


The real irony is, if compilers were as keen on exploiting undefined 
behaviour as you believe, then there /would/ be a portable 
standards-conforming way to do this:

if ((x != 0) && (x != 1)) 1/0;

Any other undefined behaviour would do in place of "1/0".

>
>> In most cases, with modern tools, bool and an unsigned char will have
>> the same efficiency for the same job.  bool obviously "wins" in such cases.
>
> If an expression which will always yield 0 or 1 is stored into a _Bool, a
> compiler will have no choice but to generate unnecessarily inefficient
> code unless either:
>
>    1. It can tell that the value will always be 0 or 1

True.  But often it /can/ tell that the value will always be 0 or 1. 
And thereafter, it can generate more efficient code based on that 
knowledge.  Expressions that combine the booleans, or that can make use 
of integer select or conditional move instructions are going to be more 
efficient.

In short, there is a reason why "bool" was added to the language, and 
why it is specified as it is.  It exists because it gives a good, clean, 
efficient, and clear way to express a true/false flag.

>
>    2. It can tell that all code which examines the value will work just
>       fine with anything that the expression could yield (e.g. the
>       expression had type "unsigned char", and everything that reads the
>       variable tests whether it's non-zero).
>

[toc] | [prev] | [next] | [standalone]


#93598

Fromsupercat@casperkitty.com
Date2016-09-15 22:02 -0700
Message-ID<dd046188-15a4-4276-8905-4459d338e08e@googlegroups.com>
In reply to#93586
On Thursday, September 15, 2016 at 5:48:06 PM UTC-5, David Brown wrote:
> The point is, if the function's return type is "bool", then you already 
> know it can only return true or false.  You don't need to add it to the 
> function's name, or use the !! combination.  And if a function's return 
> type is /not/ bool, then you already know it can yield other values - 
> but you also know that converting it to a bool will force it to true or 
> false.

Under what defined conditions can the function call

   fread(&ch, 1, 1, somefile)

yield a value other than 0 or 1?  I suppose that if someFile weren't a
valid FILE* the function could do anything, but that would be true even
if the return type were _Bool.

[toc] | [prev] | [next] | [standalone]


#93603

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-16 09:56 +0200
Message-ID<nrg8iq$rre$1@dont-email.me>
In reply to#93598
On 16/09/16 07:02, supercat@casperkitty.com wrote:
> On Thursday, September 15, 2016 at 5:48:06 PM UTC-5, David Brown wrote:
>> The point is, if the function's return type is "bool", then you already 
>> know it can only return true or false.  You don't need to add it to the 
>> function's name, or use the !! combination.  And if a function's return 
>> type is /not/ bool, then you already know it can yield other values - 
>> but you also know that converting it to a bool will force it to true or 
>> false.
> 
> Under what defined conditions can the function call
> 
>    fread(&ch, 1, 1, somefile)
> 
> yield a value other than 0 or 1?  I suppose that if someFile weren't a
> valid FILE* the function could do anything, but that would be true even
> if the return type were _Bool.
> 

You are grabbing at straws and trying to turn them into an argument.

OK, I should have written "if a function's return type is not bool, then
you already know it is possible that it may yield other values, unless
the compiler has the function definition available during compilation of
the function's caller, or it knows the exact specification of the
function because it is defined in the C standards".

Happy now?

[toc] | [prev] | [next] | [standalone]


#93622

Fromsupercat@casperkitty.com
Date2016-09-16 07:34 -0700
Message-ID<60b625eb-9e50-434f-9be0-d37b1c2455a9@googlegroups.com>
In reply to#93603
On Friday, September 16, 2016 at 2:56:22 AM UTC-5, David Brown wrote:
> OK, I should have written "if a function's return type is not bool, then
> you already know it is possible that it may yield other values, unless
> the compiler has the function definition available during compilation of
> the function's caller, or it knows the exact specification of the
> function because it is defined in the C standards".
> 
> Happy now?

Given:

    _Bool x = superRandomFunction(2);

where superRandomFunction is a piece of user-written code that will
return 0..N-1, how should I tell the compiler it doesn't need to generate
code to coerce x to the range 0..1?

[toc] | [prev] | [next] | [standalone]


#93650

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-16 20:31 +0200
Message-ID<nrhdqa$sgd$1@dont-email.me>
In reply to#93622
On 16/09/16 16:34, supercat@casperkitty.com wrote:
> On Friday, September 16, 2016 at 2:56:22 AM UTC-5, David Brown wrote:
>> OK, I should have written "if a function's return type is not bool, then
>> you already know it is possible that it may yield other values, unless
>> the compiler has the function definition available during compilation of
>> the function's caller, or it knows the exact specification of the
>> function because it is defined in the C standards".
>>
>> Happy now?
>
> Given:
>
>      _Bool x = superRandomFunction(2);
>
> where superRandomFunction is a piece of user-written code that will
> return 0..N-1, how should I tell the compiler it doesn't need to generate
> code to coerce x to the range 0..1?
>

Do it any way you like - try reading your compiler manual for ideas, 
such as:

	int y = superRandomFunction(2);
	if ((y != 0) && (y != 1)) __builtin_unreachable();
	bool x = y;


Or simply accept that it /does/ /not/ /matter/.  Your 
superRandomFunction will take long enough to run that the instructions 
needed to make a valid bool are likely to be negligible.

[toc] | [prev] | [next] | [standalone]


#93658

Fromsupercat@casperkitty.com
Date2016-09-16 12:32 -0700
Message-ID<4c4d9888-9cba-44e7-945d-462ef9b8b3ca@googlegroups.com>
In reply to#93650
On Friday, September 16, 2016 at 1:31:51 PM UTC-5, David Brown wrote:
> Do it any way you like - try reading your compiler manual for ideas, 
> such as:
> 
> 	int y = superRandomFunction(2);
> 	if ((y != 0) && (y != 1)) __builtin_unreachable();
> 	bool x = y;

That seems rather bulky; it also takes on faith that a compiler will
happen to recognize whatever particular pattern one is using.  If a
compiler doesn't happen to recognize a particular pattern, such hacks
may make code less efficient rather than more.

> Or simply accept that it /does/ /not/ /matter/.  Your 
> superRandomFunction will take long enough to run that the instructions 
> needed to make a valid bool are likely to be negligible.

Compiler writers seem to believe that making something like:

    unsigned mul(unsigned short x, unsigned short y) { return x*y; }

behave the way the authors of the Standard expected compilers to behave
when they wrote the rules for unsigned short promotions, would be an
unacceptable impediment to efficiency.  I would suggest that the efficiency
gains from allowing compilers more latitude over the effect of writing
something other than 0 or 1 to a _Bool would far exceed the efficiency
gains from making the above function behave wonky, even on commonplace
hardware, if x*y exceeds INT_MAX, while being far less astonishing.

[toc] | [prev] | [next] | [standalone]


#93695

FromDavid Brown <david.brown@hesbynett.no>
Date2016-09-17 23:30 +0200
Message-ID<nrkclk$g50$1@dont-email.me>
In reply to#93658
On 16/09/16 21:32, supercat@casperkitty.com wrote:
> On Friday, September 16, 2016 at 1:31:51 PM UTC-5, David Brown wrote:
>> Do it any way you like - try reading your compiler manual for ideas,
>> such as:
>>
>> 	int y = superRandomFunction(2);
>> 	if ((y != 0) && (y != 1)) __builtin_unreachable();
>> 	bool x = y;
>
> That seems rather bulky; it also takes on faith that a compiler will
> happen to recognize whatever particular pattern one is using.  If a
> compiler doesn't happen to recognize a particular pattern, such hacks
> may make code less efficient rather than more.

It's an implementation-dependent solution, based on a compiler extension 
supported by gcc, clang, and perhaps other compilers.

And like any other implementation-dependent hint, you would put it in a 
macro so that you can be a little more portable - your macro can be 
easily changed to suit the compiler (or to have no effect, if the 
compiler does not have a suitable construct).

The macro I use for gcc is:

extern void __attribute__((error("Assume failed"))) assumeFailed(void);
#define assume(x) \
         do { \
                 if (__builtin_constant_p(x)) { \
                         if (!(x)) { \
                                 assumeFailed(); \
                         } \
                 } \
                 if (!(x)) __builtin_unreachable(); \
         } while (0)

If the compiler is able to check the assumption at compile time, and 
finds that it fails, then I get a compile time error - which is the 
ideal time to spot such errors.

Then the code would be:

	int y = superRandomFunction(2);
	assume((y == 0) || (y == 1));
	bool x = y;

It is hard to get less "bulky" than that, except perhaps by omitting 
some of the parentheses.

And yes, gcc understands this construct and optimises appropriately.


>
>> Or simply accept that it /does/ /not/ /matter/.  Your
>> superRandomFunction will take long enough to run that the instructions
>> needed to make a valid bool are likely to be negligible.
>
> Compiler writers seem to believe that making something like:
>
>      unsigned mul(unsigned short x, unsigned short y) { return x*y; }
>
> behave the way the authors of the Standard expected compilers to behave
> when they wrote the rules for unsigned short promotions, would be an
> unacceptable impediment to efficiency.  I would suggest that the efficiency
> gains from allowing compilers more latitude over the effect of writing
> something other than 0 or 1 to a _Bool would far exceed the efficiency
> gains from making the above function behave wonky, even on commonplace
> hardware, if x*y exceeds INT_MAX, while being far less astonishing.
>

People use bools all the time, and most programmers are happy with the 
way they work.  People multiply all the time, and seem to do so 
successfully with the rules of C as laid out in the standard.  In 
particular, they usually are happy to do it using int or unsigned int, 
and let the compiler figure out when it can use 16x16->32 bit multiply 
instructions, or whatever is the most efficient at the time - that sort 
of detail is the compiler's job.

[toc] | [prev] | [next] | [standalone]


#93551

FromBartC <bc@freeuk.com>
Date2016-09-15 18:25 +0100
Message-ID<nrelhb$kri$1@dont-email.me>
In reply to#93528
On 15/09/2016 11:37, David Brown wrote:
> On 15/09/16 02:06, supercat@casperkitty.com wrote:
>> On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
>>> Programmers should use _Bool or bool because it's substantially clearer
>>> than using unsigned char to represent a true/false condition.
>>
>> What's the advantage of using a less-efficient type versus a user-defined
>> "flag" type could allow more efficient code generation?
>>
>
> As Keith says, bool is clearer and therefore better.  Clarity is not
> necessarily the overriding factor, but it is usually very important.
>
> Remember also that bool has another useful property - any assignment to
> a bool variable will give it the value 0 or 1, unless you /really/ go
> out of your way to mess things up for yourself (with pointer casts and
> the like).  This is a useful feature you can rely on - and the compiler
> can rely on it too.

But that would have been useful with *any* int types that are expected 
to occupy only a small range of legal values. Such as 1..7, or the enums 
(red, green, blue).

Just like Pascal. But nothing of the sort is done. Any int values seems 
to be completely interchangeable. The language hardly even cares if you 
assign a 32-bit int to an 8-bit one, or signed to unsigned.

So why bother with one tiny aspect of that with _Bool?

Whatever _Bool does can be achieved with explicit conversion (eg. using 
the !! operators)


-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#93569

Fromluser droog <luser.droog@gmail.com>
Date2016-09-15 12:35 -0700
Message-ID<5180b836-9506-49bf-b1a1-9a540a6c8f9a@googlegroups.com>
In reply to#93551
On Thursday, September 15, 2016 at 12:25:16 PM UTC-5, Bart wrote:
> On 15/09/2016 11:37, David Brown wrote:
> > On 15/09/16 02:06, supercat@casperkitty.com wrote:
> >> On Wednesday, September 14, 2016 at 4:34:30 PM UTC-5, Keith Thompson wrote:
> >>> Programmers should use _Bool or bool because it's substantially clearer
> >>> than using unsigned char to represent a true/false condition.
> >>
> >> What's the advantage of using a less-efficient type versus a user-defined
> >> "flag" type could allow more efficient code generation?
> >>
> >
> > As Keith says, bool is clearer and therefore better.  Clarity is not
> > necessarily the overriding factor, but it is usually very important.
> >
> > Remember also that bool has another useful property - any assignment to
> > a bool variable will give it the value 0 or 1, unless you /really/ go
> > out of your way to mess things up for yourself (with pointer casts and
> > the like).  This is a useful feature you can rely on - and the compiler
> > can rely on it too.
> 
> But that would have been useful with *any* int types that are expected 
> to occupy only a small range of legal values. Such as 1..7, or the enums 
> (red, green, blue).
> 
> Just like Pascal. But nothing of the sort is done. Any int values seems 
> to be completely interchangeable. The language hardly even cares if you 
> assign a 32-bit int to an 8-bit one, or signed to unsigned.
> 
> So why bother with one tiny aspect of that with _Bool?
> 
> Whatever _Bool does can be achieved with explicit conversion (eg. using 
> the !! operators)
> 

This is pretty much what I do. If I need a bool, I use int.
Mostly I want bools as flags in my structures. And structs 
are always in the headers. So every other C file would have to 
include stdbool first, just to read the headers.

It's doable. But I find using int to be a smaller headache.

[toc] | [prev] | [next] | [standalone]


Page 2 of 5 — ← Prev page 1 [2] 3 4 5  Next page →

Back to top | Article view | comp.lang.c


csiph-web