Boolean data type?

Discussion in 'C Programming' started by Martin Wells, Sep 22, 2007.

  1. Martin Wells

    Martin Wells Guest

    I come from C++, and there's a type called "bool" in C++. It works
    exactly like any other integer type except that when promoted, it
    either becomes a one or a zero, so you can you bitwise operators as if
    they were logical operators:

    bool a = 5, b = 6;

    if (a == b) DoSomething; /* This will execute */

    What type is commonly used in C for playing around with boolean
    values?

    I'm writing code for an embedded systems project so I'll *really* have
    to watch how much memory I'm using... so would it be wise to be
    returning "int" from functions that I would otherwise (in C++) return
    a bool from? For example

    int QueryBit(char unsigned const *const pc, unsigned const index)
    {
    return *pc & (1U << index);
    }

    (Let's leave alone for the moment the issue of whether this should
    instead be a macro)

    I suppose I'm asking two questions:

    a) What type is commonly used for booleans?
    b) What type is commonly used for booleans when you've to go easy
    on memory consumption?

    Martin
    Martin Wells, Sep 22, 2007
    #1
    1. Advertising

  2. Martin Wells

    pete Guest

    Martin Wells wrote:
    >
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators as if
    > they were logical operators:
    >
    > bool a = 5, b = 6;
    >
    > if (a == b) DoSomething; /* This will execute */
    >
    > What type is commonly used in C for playing around with boolean
    > values?


    int a = 5, b = 6;

    if (!a == !b) DoSomething; /* This will execute */

    --
    pete
    pete, Sep 22, 2007
    #2
    1. Advertising

  3. Martin Wells

    Ian Collins Guest

    Martin Wells wrote:
    >
    > I'm writing code for an embedded systems project so I'll *really* have
    > to watch how much memory I'm using... so would it be wise to be
    > returning "int" from functions that I would otherwise (in C++) return
    > a bool from? For example
    >
    >
    > I suppose I'm asking two questions:
    >
    > a) What type is commonly used for booleans?
    > b) What type is commonly used for booleans when you've to go easy
    > on memory consumption?


    In that case, if I didn't have access to a C99 compiler, or a compiler
    with bool as an extension, I'd use an enum. Most embedded compilers I
    have used have options to minimise the size of enums by using the
    smallest type than holds the range of the enum values.

    --
    Ian Collins.
    Ian Collins, Sep 22, 2007
    #3
  4. Martin Wells

    user923005 Guest

    On Sep 21, 4:22 pm, Martin Wells <> wrote:
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators as if
    > they were logical operators:
    >
    > bool a = 5, b = 6;
    >
    > if (a == b) DoSomething; /* This will execute */
    >
    > What type is commonly used in C for playing around with boolean
    > values?
    >
    > I'm writing code for an embedded systems project so I'll *really* have
    > to watch how much memory I'm using... so would it be wise to be
    > returning "int" from functions that I would otherwise (in C++) return
    > a bool from? For example
    >
    > int QueryBit(char unsigned const *const pc, unsigned const index)
    > {
    > return *pc & (1U << index);
    >
    > }
    >
    > (Let's leave alone for the moment the issue of whether this should
    > instead be a macro)
    >
    > I suppose I'm asking two questions:
    >
    > a) What type is commonly used for booleans?
    > b) What type is commonly used for booleans when you've to go easy
    > on memory consumption?


    If you have C99 {where _Bool is a type} then:

    ISO/IEC 9899:1999 (E) ©ISO/IEC
    7.16 Boolean type and values <stdbool.h>
    1 The header <stdbool.h> defines four macros.
    2 The macro
    bool
    expands to _Bool.
    3 The remaining three macros are suitable for use in #if preprocessing
    directives. They are:
    true
    which expands to the integer constant 1,
    false
    which expands to the integer constant 0, and
    _ _bool_true_false_are_defined
    which expands to the integer constant 1.
    4 Notwithstanding the provisions of 7.1.3, a program may undefine and
    perhaps then redefine the macros bool, true, and false.213)
    213) See "future library directions" (7.26.7).
    252 Library §7.16

    Else just use enums or macros. Typically as enum:

    typedef boolean_type {false=0, true} bool_t;

    Typically as macro:

    #ifndef FALSE
    #define FALSE 0
    #endif

    #ifndef TRUE
    #define TRUE !FALSE
    #endif
    user923005, Sep 22, 2007
    #4
  5. Martin Wells <> writes:
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators as if
    > they were logical operators:
    >
    > bool a = 5, b = 6;
    >
    > if (a == b) DoSomething; /* This will execute */
    >
    > What type is commonly used in C for playing around with boolean
    > values?


    <http://www.c-faq.com/>, section 9.

    > I'm writing code for an embedded systems project so I'll *really* have
    > to watch how much memory I'm using... so would it be wise to be
    > returning "int" from functions that I would otherwise (in C++) return
    > a bool from?

    [...]

    Using a type smaller than int for booleans is likely to save space,
    but is also likely (but not certain) to increase code size. If your
    CPU can load, store, and manipulate bytes as easily as words, using a
    1-byte type makes sense; if not, int is likely to be a good choice.

    If you want to have, say, large arrays of booleans, the tradeoffs
    change. It might even make sense to store a boolean value in each bit
    (but you'll have to write your own bitwise masking and shifting code
    to do this -- or find something that's already been written).

    Assuming C99's _Bool is not available, my favorite form is something
    like:

    typedef enum { false, true } bool;

    This allows the compiler to decide how big to make a bool. But watch
    out for name collisions if another library you're using defines its
    own boolean type.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 22, 2007
    #5
  6. Martin Wells wrote:
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators as if
    > they were logical operators:
    >
    > bool a = 5, b = 6;
    >
    > if (a == b) DoSomething; /* This will execute */
    >
    > What type is commonly used in C for playing around with boolean
    > values?


    It used to be that C programmers did not rely on the boolean crutch,
    since various kinds of integers serve quite well without losing
    information. However, for some reason this expensive way to store
    single bits has enough appeal that we now have:

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

    int main(void)
    {
    bool a_bool = 5, b_bool = 6; /* <stdbool.h> causes 'bool' to
    expand to '_Bool' */
    _Bool a_Bool = 5, b_Bool = 6;
    unsigned int a_int = 5, b_int = 6;

    printf("using 'bool' versions of a and b\n"
    "a_bool = %u, compares %sequal to 'true'\n"
    "b_bool = %u, compares %sequal to 'true'\n"
    "the value of a_bool == b_bool is %u\n"
    "the value of (a_bool == b_bool) == true is %u\n\n",
    a_bool, (a_bool == true) ? "" : "not ",
    b_bool, (b_bool == true) ? "" : "not ",
    a_bool == b_bool, (a_bool == b_bool) == true);


    printf("using '_Bool' versions of a and b\n"
    "a_Bool = %u, compares %sequal to 'true'\n"
    "b_Bool = %u, compares %sequal to 'true'\n"
    "the value of a_Bool == b_Bool is %u\n"
    "the value of (a_Bool == b_Bool) == true is %u\n\n",
    a_Bool, (a_Bool == true) ? "" : "not ",
    b_Bool, (b_Bool == true) ? "" : "not ",
    a_Bool == b_Bool, (a_Bool == b_Bool) == true);

    printf("using 'unsigned int' versions of a and b\n"
    "a_bool = %u, compares %sequal to 'true'\n"
    "b_bool = %u, compares %sequal to 'true'\n"
    "the value of a_int == b_int is %u\n"
    "the value of (a_int == b_int) == true is %u\n\n",
    a_int, (a_int == true) ? "" : "not ",
    b_int, (b_int == true) ? "" : "not ",
    a_int == b_int, (a_int == b_int) == true);

    return 0;
    }

    [output]
    using 'bool' versions of a and b
    a_bool = 1, compares equal to 'true'
    b_bool = 1, compares equal to 'true'
    the value of a_bool == b_bool is 1
    the value of (a_bool == b_bool) == true is 1

    using '_Bool' versions of a and b
    a_Bool = 1, compares equal to 'true'
    b_Bool = 1, compares equal to 'true'
    the value of a_Bool == b_Bool is 1
    the value of (a_Bool == b_Bool) == true is 1

    using 'unsigned int' versions of a and b
    a_bool = 5, compares not equal to 'true'
    b_bool = 6, compares not equal to 'true'
    the value of a_int == b_int is 0
    the value of (a_int == b_int) == true is 0
    Martin Ambuhl, Sep 22, 2007
    #6
  7. Martin Wells

    CBFalconer Guest

    Martin Wells wrote:
    >
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators
    > as if they were logical operators:


    There is no boolean type in C90. C99 has a _Bool type.
    >

    .... snip ...
    >
    > I suppose I'm asking two questions:
    >
    > a) What type is commonly used for booleans?
    > b) What type is commonly used for booleans when you've to
    > go easy on memory consumption?


    >From N869:


    [#6] For each of the signed integer types, there is a
    corresponding (but different) unsigned integer type
    (designated with the keyword unsigned) that uses the same
    amount of storage (including sign information) and has the
    same alignment requirements. The type _Bool and the
    unsigned integer types that correspond to the standard
    signed integer types are the standard unsigned integer
    types. The unsigned integer types that correspond to the
    extended signed integer types are the extended unsigned
    integer types. The standard and extended unsigned integer
    types are collectively called unsigned integer types.27)

    If you #include <stdbool.h> then bool is defined (as _Bool), and:

    B.15 Boolean type and values <stdbool.h>

    bool
    true
    false
    __bool_true_false_are_defined

    Note that this is only in C99.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Sep 22, 2007
    #7
  8. Martin Wells

    Ark Khasin Guest

    Ian Collins wrote:
    > Martin Wells wrote:
    >> I'm writing code for an embedded systems project so I'll *really* have
    >> to watch how much memory I'm using... so would it be wise to be
    >> returning "int" from functions that I would otherwise (in C++) return
    >> a bool from? For example
    >>
    >>
    >> I suppose I'm asking two questions:
    >>
    >> a) What type is commonly used for booleans?
    >> b) What type is commonly used for booleans when you've to go easy
    >> on memory consumption?

    >
    > In that case, if I didn't have access to a C99 compiler, or a compiler
    > with bool as an extension, I'd use an enum. Most embedded compilers I
    > have used have options to minimise the size of enums by using the
    > smallest type than holds the range of the enum values.
    >

    I tried and adopted enum until I got a new version of the compiler that
    supported _Bool. To my astonishment, _Bool generated much more efficient
    code than the enum.
    Still, honestly, there are very few precious cases where bool of any
    sort has merits. They AFAIK are limited to temporarily storing results
    of bulky comparisons and used only to improve readability (since the
    compiler should optimize them out).
    bool return type looks evil since the compiler effectively does
    something like return !!x; it's an overhead I could do without.
    -- Ark
    Ark Khasin, Sep 22, 2007
    #8
  9. On 2007-09-21 23:22, Martin Wells <> wrote:
    >
    > I come from C++, and there's a type called "bool" in C++. It works
    > exactly like any other integer type except that when promoted, it
    > either becomes a one or a zero, so you can you bitwise operators as if
    > they were logical operators:
    >
    > bool a = 5, b = 6;
    >
    > if (a == b) DoSomething; /* This will execute */
    >
    > What type is commonly used in C for playing around with boolean
    > values?
    >
    > I'm writing code for an embedded systems project so I'll *really* have
    > to watch how much memory I'm using... so would it be wise to be
    > returning "int" from functions that I would otherwise (in C++) return
    > a bool from? For example
    >
    > int QueryBit(char unsigned const *const pc, unsigned const index)
    > {
    > return *pc & (1U << index);
    > }


    Worrying about the memory consumption of return types is probably
    futile. On most systems the return value is passed in a register (if it
    fits), so it always takes the same space and that space isn't in memory.

    Also worrying about the size of simple variables probably doesn't make
    much sense unless you really have a lot of them or are making heavy use
    of recursive functions.

    Where is the size really matters is in arrays. Storing boolean values in
    an int[] wastes a lot of space (probably 15 or 31 bits per value,
    depending on your platform). By using bool (if available), enum or char,
    you may be able to reduce the overhead to 7 bits per value. But an array
    element can never use less than 8 bits in C, so if that's still too
    much, you should consider storing them in an array of unsigned int,
    where each element holds the appropriate number of bits.


    hp


    --
    _ | Peter J. Holzer | I know I'd be respectful of a pirate
    |_|_) | Sysadmin WSR | with an emu on his shoulder.
    | | | |
    __/ | http://www.hjp.at/ | -- Sam in "Freefall"
    Peter J. Holzer, Sep 22, 2007
    #9
  10. "Martin Wells" <> wrote in message
    news:...
    >
    > What type is commonly used in C for playing around with boolean
    > values?
    >
    > a) What type is commonly used for booleans?
    > b) What type is commonly used for booleans when you've to go easy
    > on memory consumption?
    >

    int by convention.

    So

    int is_prime(int N)

    for instance.

    Not

    typedef int BOOL;

    BOOL is_prime(int N)

    bool breaks libraries. You don't want everyone who happens to cut and paste
    your is_prime function to be tied to BOOL throughout his code.

    However unsigned char would work. (A pathological implementation could make
    1 a trap value for characters).

    Space is only a problem when you need several booleans on the go - eg an
    array of a thousand of the things.

    Method 1: use a bitfield. This will often save the most. Typically there
    will be a integer field that doesn't need the full 32 bits and you can raid
    for the boolean, thus giving you a zero memory footprint.
    Method 2: use unsigned char for the array, convert to in the minute you read
    and write it. This is very simple and fast.
    Method 3: write a getbit() and setbit() function to manage a flat array of
    unsigned chars. This is a nuisance, but gives you total control, over bit
    packing. It will probably be slightly slower than the bitfield, and
    considerably slower than the char array.
    Method 4: (for the crazed). Typically you can compress a bitstream. This
    will really squeeze down your memory take, at a cost of massive overhead.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Sep 22, 2007
    #10
  11. Martin Wells

    Army1987 Guest

    On Fri, 21 Sep 2007 17:03:51 -0700, user923005 wrote:

    > Typically as macro:
    >
    > #ifndef FALSE
    > #define FALSE 0
    > #endif
    >
    > #ifndef TRUE
    > #define TRUE !FALSE

    What's wrong with
    #define TRUE 1
    ? If you want to do that, put parentheses at least, so that, er...
    TRUE[arr] will do the right thing... :)
    > #endif


    --
    Army1987 (Replace "NOSPAM" with "email")
    A hamburger is better than nothing.
    Nothing is better than eternal happiness.
    Therefore, a hamburger is better than eternal happiness.
    Army1987, Sep 22, 2007
    #11
  12. Martin Wells

    pete Guest

    Malcolm McLean wrote:

    > Method 3: write a getbit() and setbit()
    > function to manage a flat array of unsigned chars.
    > This is a nuisance, but gives you total control, over bit
    > packing. It will probably be slightly slower than the bitfield, and
    > considerably slower than the char array.


    I use macros. The last time that I tried to use a bitfield,
    about ten years ago, the bitfield was much slower.
    /*
    ** Some bitwise macros for unsigned U
    */
    #define READ_UBIT(U, N) ((U) >> (N) & 1u)
    #define FLIP_UBIT(U, N) ((void)((U) ^= 1u << (N)))
    #define SET_UBIT(U, N) ((void)((U) |= 1u << (N)))
    #define CLEAR_UBIT(U, N) ((void)((U) &= ~(1u << (N))))

    --
    pete
    pete, Sep 22, 2007
    #12
  13. Martin Wells <> wrote:
    >I come from C++, and there's a type called "bool"
    >...
    > a) What type is commonly used for booleans?


    I use bool, (partially because some of my code must be written in the
    mythical C/C++ language):

    #ifndef __cplusplus
    typedef enum
    {
    false = 0,
    true = !false
    } bool;
    #endif /* __cplusplus */

    > b) What type is commonly used for booleans when you've to go easy
    >on memory consumption?


    That depends on the compiler and target processor. A C compiler for
    the 8051 architecture, for example, could use single bits without any
    additional masking and shifting code.
    If you have a very large number of booleans, a library providing bit
    vector operations on a char array is probably a good choice.
    --
    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Sep 22, 2007
    #13
  14. "Malcolm McLean" <> writes:
    [...]
    > However unsigned char would work. (A pathological implementation could
    > make 1 a trap value for characters).


    No, it couldn't. (I assume that by "characters" you mean values of
    type 'char' and 'signed char'.)

    There's no such thing as a "trap value"; there are only trap
    representations. All three character types are guaranteed to be able
    to represent the values 0 and 1 (in fact, they're all guaranteed to be
    able to represent any values in the range 0..127).

    Using plain char lets the compiler choose whichever representation,
    signed or unsigned, gives the best performance (though there's no
    guarantee that the compiler actually makes its choice based on
    performane).

    But if you're only dealing with singleton objects and values, int is
    probably the best choice.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 22, 2007
    #14
  15. Roberto Waltman <> writes:
    > Martin Wells <> wrote:
    >>I come from C++, and there's a type called "bool"
    >>...
    >> a) What type is commonly used for booleans?

    >
    > I use bool, (partially because some of my code must be written in the
    > mythical C/C++ language):
    >
    > #ifndef __cplusplus
    > typedef enum
    > {
    > false = 0,
    > true = !false
    > } bool;
    > #endif /* __cplusplus */


    That's more complicated than it needs to be; you're telling the
    compiler things it already knows. Using !false rather than just 1
    buys you nothing; there's no chance that the value of !false will ever
    be anything other than 1. And specifying *any* values is superfluous;
    the language guarantees that the values will be 0 and 1, respectively.

    typedef enum { false, true } bool;

    is entirely adequate, though I *might* write:

    typedef enum { false=0, true=1 } bool;

    just for emphasis.

    In fact, here's what I might do (if I really wanted compatibility with
    both C and C++):

    #ifdef __cplusplus
    /* bool, false, and true are predefined. */
    #elif __STDC_VERSION__ >= 199901L
    #include <stdbool.h>
    #else
    typedef enum { false, true } bool;
    #endif

    Note that C99's 'bool' has certain properties that the enum type lacks
    (and C++'s 'bool'probably does too); you just have to carefully write
    your code to avoid excercising any of the differences.

    >> b) What type is commonly used for booleans when you've to go easy
    >>on memory consumption?

    >
    > That depends on the compiler and target processor. A C compiler for
    > the 8051 architecture, for example, could use single bits without any
    > additional masking and shifting code.


    But an 8051 C compiler would have to be fairly clever to generate code
    that accesses single-bit objects, since there's no really good way to
    specify that in standard C. Or perhaps the compiler could provide
    single-bit objects as an extension. Quite possibly compilers already
    do this.

    > If you have a very large number of booleans, a library providing bit
    > vector operations on a char array is probably a good choice.


    Agreed.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 22, 2007
    #15
  16. Keith Thompson <> wrote:
    >Roberto Waltman <> writes:
    >>...
    >> typedef enum
    >> {
    >> false = 0,
    >> true = !false
    >> } bool;

    >
    >That's more complicated than it needs to be; you're telling the
    >compiler things it already knows. Using !false rather than just 1
    >buys you nothing; there's no chance that the value of !false will ever
    >be anything other than 1. And specifying *any* values is superfluous;
    >the language guarantees that the values will be 0 and 1, respectively.
    >
    > typedef enum { false, true } bool;
    >
    >is entirely adequate, though I *might* write:
    >
    > typedef enum { false=0, true=1 } bool;
    >
    >just for emphasis.


    Correct, of course, but I would not use the first version.
    I worked on a few projects with coding standards that required to
    provide values to all enums, instead of relying on the compiler
    default handling. It made sense there, to give one example, with more
    than a hundred values for an enum used for function error return
    codes, separated in ranges for each subsystem. We did not want values
    to change when new error codes were added. On top of that, in some
    cases it may be desirable to be able to change the order of the
    declarations, without changing their value (group all fatal errors
    together, etc.):

    typedef enum
    {
    ...
    STAT_COMMS_OK = 0x1000;
    STAT_COMMS_LINK_DOWN = 0x1001;
    STAT_COMMS_BAD_CRC = 0x1002
    ...
    STAT_DB_OK = 0x2000;
    STAT_DB_BAD_OID = 0x2001;
    ... /* etc. */
    } STATUS;

    I have adopted that practice and, for consistency, I use even in
    obvious cases like the enum above. The !false instead of 1 is to
    emphasize these are logical values. (Personal taste only, will not
    defend this very vigorously.)

    >...
    >But an 8051 C compiler would have to be fairly clever to generate code
    >that accesses single-bit objects, since there's no really good way to
    >specify that in standard C. Or perhaps the compiler could provide
    >single-bit objects as an extension. Quite possibly compilers already
    >do this.


    Just checked the online documentation for Keil's CX51 compiler.
    It provides a 'bit' data type as a language extension. (With some
    limitations: it is not possible to declare a bit array, or a pointer
    to a bit variable. The number of bit variables is limited to 128 by
    the size of the 8051's internal bit addressable memory)

    --
    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Sep 22, 2007
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Newton
    Replies:
    0
    Views:
    2,630
    Mike Newton
    Jul 27, 2004
  2. Ramprasad A Padmanabhan

    using char as boolean data type

    Ramprasad A Padmanabhan, Sep 1, 2003, in forum: C Programming
    Replies:
    10
    Views:
    616
  3. KimmoA

    The lack of a boolean data type in C

    KimmoA, Dec 19, 2006, in forum: C Programming
    Replies:
    76
    Views:
    1,380
    Malcolm McLean
    Jan 6, 2007
  4. J Leonard
    Replies:
    4
    Views:
    12,598
    Mark Space
    Jan 19, 2008
  5. Metre Meter
    Replies:
    7
    Views:
    350
    Metre Meter
    Aug 6, 2010
Loading...

Share This Page