bool to int conversion
Solution 1
int x = 4<5;
Completely portable. Standard conformant. bool
to int
conversion is implicit!
§4.7/4 from the C++ 11 or 14 Standard, §7.8/4 from the C++ 17 Standard, §7.3.9/2 from the 20 Standard says (Integral Conversion)
If the source type is bool, the value
false
is converted to zero and the valuetrue
is converted to one.
As for C, as far as I know there is no bool
in C. (before 1999) So bool
to int
conversion is relevant in C++ only. In C, 4<5
evaluates to int
value, in this case the value is 1
, 4>5
would evaluate to 0
.
EDIT: Jens in the comment said, C99 has _Bool
type. bool
is a macro defined in stdbool.h
header file. true
and false
are also macro defined in stdbool.h
.
§7.16 from C99 says,
The macro
bool
expands to _Bool.[..]
true
which expands to the integer constant1
,false
which expands to the integer constant0
,[..]
Solution 2
You tagged your question [C] and [C++] at the same time. The results will be consistent between the languages, but the structure of the the answer is different for each of these languages.
In C language your examples has no relation to bool
whatsoever (that applies to C99 as well). In C language relational operators do not produce bool
results. Both 4 > 5
and 4 < 5
are expressions that produce results of type int
with values 0
or 1
. So, there's no "bool to int conversion" of any kind taking place in your examples in C.
In C++ relational operators do indeed produce bool
results. bool
values are convertible to int
type, with true
converting to 1
and false
converting to 0
. This is guaranteed by the language.
P.S. C language also has a dedicated boolean type _Bool
(macro-aliased as bool
), and its integral conversion rules are essentially the same as in C++. But nevertheless this is not relevant to your specific examples in C. Once again, relational operators in C always produce int
(not bool
) results regardless of the version of the language specification.
Solution 3
Section 6.5.8.6 of the C standard says:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.) The result has type int.
Solution 4
There seems to be no problem since the int to bool cast is done implicitly. This works in Microsoft Visual C++, GCC and Intel C++ compiler. No problem in either C or C++.
Related videos on Youtube
Comments
-
pic11 about 3 years
How portable is this conversion. Can I be sure that both assertions pass?
int x = 4<5; assert(x==1); x = 4>5; assert(x==0);
Don't ask why. I know that it is ugly. Thank you.
-
harper over 13 yearsWhy don't your change the first expression? You can write
assert(x!=0)
. Even if bool(true) converts portable to the int(1), the "not false" asserts has a more readable expression. -
Martin York over 13 yearsWhy not:
assert( 4 < 5);
andassert(!( 4 > 5));
-
R.. GitHub STOP HELPING ICE over 13 years@harper: Using the required value of a comparison expression is perfectly reasonable.
-
harper over 13 years@R._ When the question is if the bool-to-int conversion gives a reasonable result, I would not rely on this. When the author has a doubt that this requirement is fullfilled, the reader could get the same problem. Especially because the value of x is not the condition to check but only a intermediate result.
-
ollb over 13 yearsI would probably write
(4 < 5) ? 1 : 0
if I really need to convert a boolean to 0 or 1. A good compiler will likely produce the same machine code and it's clearer for a human reader. -
eonil over 10 years@ollb I think most of modern compilers are good enough to optimize this.
-
Thomas Weller about 3 years@R..GitHubSTOPHELPINGICE: what's the "stop helping ice" about?
-
-
pic11 over 13 yearsThat is right, there is no bool in K&R C. I re-tagged my question as C99.
-
pic11 over 13 yearsThanks for the reference. It seems that true==1 for historical reasons.
-
AnT stands with Russia over 13 years@pic11: There was no need to retag anything. It has nothing to do with K&R or any other C. Even though there's
bool
in C99, the relational operators still produceint
in C99, notbool
. So, if it is specifically relational operators you are interested in (as in your examples), the issue still has nothing to do withbool
. -
AnT stands with Russia over 13 yearsRegardless of the version of C language and availability of
bool
/_Bool
type, relational operators in C produceint
, notbool
. I.e. even in C99, relational operators still produceint
. -
pic11 over 13 yearsNow I get it. The result of relation operator implicitly convertible to int. This is true in C, C99 and C++. Re-targed again.
-
R.. GitHub STOP HELPING ICE over 13 years@pic11: No, you don't get it. In C, including C99, the result of a comparison operator is an
int
, not abool
. No conversion happens. -
Matthew Read about 12 years"It works in some cases" isn't a good way to check for correctness, especially with unspecified versions of those tools. I prefer the approach in the other answers; they can't guarantee a particular implementation is correct, but they can guarantee what a correct implementation will do.
-
supercat over 10 yearsIs there any standards-conforming way via which a language could have a type which behaves like
bool
but does not allow its address to be taken? Many embedded systems make use of such types (often declared using the identifierbit
). On e.g. a mid-range PIC,if (bitVar1) bitVar2=1;
would be two instructions; optimal coding forif (byteVar1) byteVar2=1;
would be at least four (on many compilers, probably five). Such types can thus offer a major performance boost. -
AnT stands with Russia over 10 years@supercat: Would you please elaborate on how the "bit" version can be implemented in less instructions than the "byte" version? On the modern x84 platform the "byte" version can easily be implemented in two instructions:
cmp
andsetz
(or something similar, depending on wherebyteVar1
is stored). On top of that, if additional information is available about the value ofbyteVar1
, extra optimizations might be possible -
supercat over 10 years@AndreyT: On a mid-range PIC, if
bitvar1
is bit 3 of address 0x12, andbitvar2
is bit 6 of address 0x45, the instruction sequenceif (bitvar1) bitvar2=1
would bebtfsc 0x12,3 ; skip next instruction if bit 3 of address 0x12 is not set
followed bybsf 0x45,6 ; set bit 6 of address 0x45
. Using bytes at those addresses, the shortest possible sequence would be:movf 0x12,w ; load W with value and set Z flag iff zero
,movlw 0x01 ; load W with 1 without affecting Z
,btfss 3,2 ; Skip next instruction if Z flag set
,movwf 0x45 ; Store W to address 0x45
. -
supercat over 10 years@AndreyT: I'm not sure how many compilers would find that instruction sequence, since it requires moving the
movlw 1
before the conditional test. I suspect many would render it asmovf 0x12,w / btfsc 3,2 / goto skip / movlw 0x01 / movwf 0x45 / skip:
. Many embedded processors include instructions to directly test or set bits stored in memory, but do not include instructions to test whether memory bytes are zero, nor to directly set them to a non-zero value.