bool to int conversion

175,555

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 value true 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 constant 1, false which expands to the integer constant 0,[..]

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++.

Share:
175,555

Related videos on Youtube

pic11
Author by

pic11

I code in C, C++ and Python.

Updated on April 20, 2021

Comments

  • pic11
    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
      harper over 13 years
      Why 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
      Martin York over 13 years
      Why not: assert( 4 < 5); and assert(!( 4 > 5));
    • R.. GitHub STOP HELPING ICE
      R.. GitHub STOP HELPING ICE over 13 years
      @harper: Using the required value of a comparison expression is perfectly reasonable.
    • harper
      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
      ollb over 13 years
      I 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
      eonil over 10 years
      @ollb I think most of modern compilers are good enough to optimize this.
    • Thomas Weller
      Thomas Weller about 3 years
      @R..GitHubSTOPHELPINGICE: what's the "stop helping ice" about?
  • pic11
    pic11 over 13 years
    That is right, there is no bool in K&R C. I re-tagged my question as C99.
  • pic11
    pic11 over 13 years
    Thanks for the reference. It seems that true==1 for historical reasons.
  • AnT stands with Russia
    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 produce int in C99, not bool. So, if it is specifically relational operators you are interested in (as in your examples), the issue still has nothing to do with bool.
  • AnT stands with Russia
    AnT stands with Russia over 13 years
    Regardless of the version of C language and availability of bool/_Bool type, relational operators in C produce int, not bool. I.e. even in C99, relational operators still produce int.
  • pic11
    pic11 over 13 years
    Now 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
    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 a bool. No conversion happens.
  • Matthew Read
    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
    supercat over 10 years
    Is 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 identifier bit). On e.g. a mid-range PIC, if (bitVar1) bitVar2=1; would be two instructions; optimal coding for if (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
    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 and setz (or something similar, depending on where byteVar1 is stored). On top of that, if additional information is available about the value of byteVar1, extra optimizations might be possible
  • supercat
    supercat over 10 years
    @AndreyT: On a mid-range PIC, if bitvar1 is bit 3 of address 0x12, and bitvar2 is bit 6 of address 0x45, the instruction sequence if (bitvar1) bitvar2=1 would be btfsc 0x12,3 ; skip next instruction if bit 3 of address 0x12 is not set followed by bsf 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
    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 as movf 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.