-2

As I know, Boolean is basically a char datatype, one byte, 0x00 or 0x01. Also, as I know, Integer is multiple bytes.

bool foo () {
    return true; // I guess is 0x01 one byte
    return 1; // I guess is 0x00000001 four bytes (depend on the platform)
}

Why do both returns work?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Albert Shown
  • 230
  • 7
  • Since it is returning `bool`, use the corresponding values `true` and `false` for consistency. – Eugene Sh. Jan 04 '23 at 17:28
  • 2
    Both work because C considers any number other than `0` to be true, and `0` of any type is considered false. – Barmar Jan 04 '23 at 17:29
  • 2
    *As I know, Boolean is basically a char datatype* - this is not true. It is `_Bool`, whose underlying memory layout is only defined to be large enough to hold values `0` and `1`. – Eugene Sh. Jan 04 '23 at 17:29
  • 3
    Ironically, for a language all about binary computing, "boolean" values were a serious afterthought in C. This is largely because a lot of things were already *logically* true or false and `1` and `0` already did the job. If your return type is `bool`, the proper thing to do is `return true`. Don't make it weird. There's an infinite number of things that also work, like `cos(0)` or `!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!0` but please don't. – tadman Jan 04 '23 at 17:29
  • Does this answer your question? [Casting int to bool in C/C++](https://stackoverflow.com/questions/31551888/casting-int-to-bool-in-c-c) – Useless Jan 04 '23 at 17:32
  • 1
    In general, C allows mixed-type expressions. If you say `a = b`, but `a` and `b` do not have the same types, the compiler will attempt to automatically convert `b`'s value to the type of `a`. Similarly, if you have a function `atype f() { btype b; b = ...; return b; }`, where the function is declared to return a value of one type ("`atype`") but you write a `return` statement involving an expression of another type (`"btype"`), the compiler will attempt to convert `b`'s value to type `atype`. – Steve Summit Jan 04 '23 at 17:40
  • If such a conversion is possible, the compiler will perform it. If the conversion is impossible, you'll get an error at compile time. (Even if the conversion is possible, you may get a warning, if someone thinks that particular conversion might be a mistake, or a bad idea. Conversions to type `bool` are almost always possible, however, with values that compare equal to `0` being considered "false", and all other values being considered "true".) – Steve Summit Jan 04 '23 at 17:40
  • Thank you guys for your comments, I agree with you, I'm just wondering why `sizeof(bool)` in all platform 99% will give you 1, which mean 1 byte like a `char` datatype. Another thing is why a Microsoft Repo will use `return 1` in a bool function like here https://github.com/microsoft/jacdac-c/blob/65a3576993b466f462b20bfa6c74757259594fa5/services/hidmouse.c#L100 – Albert Shown Jan 04 '23 at 19:02

3 Answers3

4

Here is what the C 2017 standard says about bool (aka _Bool) so "basically a char" is not correct:

An object declared as type _Bool is large enough to store the values 0 and 1. (6.2.5)

return 1 works due to automatic type conversion:

When any scalar value is converted to _Bool , the result is 0 if the value compares equal to 0; otherwise, the result is 1 (6.3.1.2)

There is no "best practice" as far as I know. I did not see it covered in MISRA C for instance. It may be covered in coding guidelines for your project(s) though. I use 0 and 1 as I favor compact code.

Allan Wind
  • 23,068
  • 5
  • 28
  • 38
  • Agreed: they are interchangeable as far as anyone familiar with C should read it. I personally prefer `true` and `false` when dealing with boolean values, as I think it better maps conceptually. But just so the OP is aware, there is a loud cohort of C people who have given me grief about that before. But +1 because using `0` and `1` is absolutely fine and idiomatic. – Dúthomhas Jan 05 '23 at 04:34
4

As others have explained, the size of a bool is not specified by the standard, so a compiler implementation is free to use any size as long as it can hold the values 0 and 1.

My clear recommendation is to use a bool type if the information is true/false by nature. Using an integer as boolean can lead to subtle errors. Consider the following (inspired by a real-life bug):

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

uint8_t isThisTrueInt(void)
{
    int x = 256;
    return x;
}

bool isThisTrueBool(void)
{
    int x = 256;
    return x;
}

int main(void)
{
    printf("%s\n", (isThisTrueInt())?"true":"false");
    printf("%s\n", (isThisTrueBool())?"true":"false");
    return 0;
}

The result is:

false
true

The point being that converting 256 to an 8-bit integer truncates to 0, i.e. "false" while conversion to bool will give "true" for any non-zero integer.

nielsen
  • 5,641
  • 10
  • 27
  • 3
    I appreciate that real-life inspired bug. Ouch. I can't get gcc to emit a warning (till you change the `int` to `uint8_t` or straight `return 256` for an overflow warning). It would have taken me forever to find that bug as it offends my sensibilities :-) – Allan Wind Jan 04 '23 at 18:41
2

As I know, Boolean is basically a char datatype, one byte, 0x00 or 0x01

That is not the case, the size of bool type is implementation-defined and is not specified in the C standard, it is usually defined in stdbool.h as of C99 and is normally something like:

#define bool  _Bool
#define false 0
#define true  1

Before that it wasn't even a mandated type. You can say that in some implementations it's equivalent to a single byte, but not always, the specification only requires that bool is large enough to hold the values 0 or 1 and this ranges from 1 bit to the largest type possible, natively long long.


What's the best practice to follow?

This is an opinion based question, still, thinking about it, I would advise to use true/false because it's a pattern used in pretty much all the languages and it'll surely be easier to understand, I must admit I'm not the best follower of such practice as I often use 0/1.

This is all overrided by your project/company coding practices or guidelines, if that's the case.


Why do both returns work?

In C, any non-zero value is considered to be true (this includes negative values) in a boolean context, whereas 0 is considered to be false as can be seen in N1570 Committee Draft of April 12, 2011 ISO/IEC 9899:201x:

§6.3.1.2 Boolean type

1 When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1.59)

Footnotes

59) NaNs do not compare equal to 0 and thus convert to 1.

anastaciu
  • 23,467
  • 7
  • 28
  • 53