Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #93399 > unrolled thread
| Started by | thiago.adams@gmail.com |
|---|---|
| First post | 2016-09-12 13:24 -0700 |
| Last post | 2016-09-17 17:14 -0700 |
| Articles | 20 on this page of 86 — 16 participants |
Back to article view | Back to comp.lang.c
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 →
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2016-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]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2016-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]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2016-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