More Fun with _Bool

Plenty of C coders implemented boolean variables long before the C99 standard introduced the _Bool type. Programmers defined TRUE and FALSE constants, they used char or short variables as toggles, or they manipulated bits in a byte to simulate binary and boolean operations. With all that going on, you’d think adding a boolean variable type to C and calling it bool would have been a no-brainer. It wasn’t.

The problem is that existing programs may have defined a variable as bool. This is most likely the reason why the new C language keywords (introduced in the C99 and C11 standards) are prefixed with an underscore.

Underscores in C are significant, though not officially. Many internal functions, variable names, and definitions use one or more underscores in their names. If you’re an experienced programmer and you see something like __var, you know that it’s some internal value you probably don’t want to mess with it. Given this condition, it’s curious to me why the C overlords decided to create new keyworks with an underscore prefix. It’s almost like a subtle message not to use the things.

Yet, you can still use bool as a variable type. You just have to include the stdbool.h header file in your code. This header file defines bool as a variable type _Bool. It’s not a typecast, it’s a #define.

Also defined in the stdbool.h header are true and false, 1 and 0 respectively.

Here is the decrementing code from last week’s Lesson, but using the bool definition:

#include <stdio.h>
#include <stdbool.h>
  
int main()
{
    bool alpha = 0;
    int i;

    for(i=0;i<10;i++)
    {
        printf("%d\n",alpha);
        alpha--;
    }

    return(0);
}

The output is the same as when the _Bool keyword is used.

You can also make _Bool arrays:

#include <stdio.h>
  
int main()
{
    _Bool a[8] = { 0, 0, 1, 0, 1, 0, 1, 0 };
    int i;

    for(i=0;i<8;i++)
        printf("%d ",a[i]);
    putchar('\n');

    return(0);
}

A _Bool array a[] is created and elements assigned at Line 6. The values are printed by using the a[i] notation in the for loop at Line 9. Here’s the output:

0 0 1 0 1 0 1 0

I think it would be clever if the C library had functions to map a boolean array to an integer type, though you’re free to code such functions on your own. ๐Ÿ˜€

And, as you may have feared, you can use _Bool pointers as well:

#include <stdio.h>
#include <stdlib.h>

int main()
{ 
    _Bool *aptr;
    int i;

    /* allocate boolean storage */
    aptr = (_Bool *)malloc( 8 * sizeof(_Bool) );
    if( aptr == NULL )
    {
        puts("Unable to allocate _Bool memory?");
        exit(1);
    }

    /* fill and display values */
    for(i=0;i<8;i++)
    {
        *(aptr+i) = 1;
        printf("%d: %d\n",i,*(aptr+i));
    }

    return(0);
}

The _Bool pointer aptr is created at Line 6. Memory is allocated for the pointer at Line 10. Because the sizeof keyword returns 1 for a _Bool, 8 bytes are actually allocated. It would be cool if the compiler allocated 8 bits, but things don’t work that way.

The for loop at Lines 18 through 22 fill the storage with ones. The *(aptr+i) notation is the pointer-equivalent of array notation, a[i], which holds true for all C language variable types. Here’s the output:

0: 1
1: 1
2: 1
3: 1
4: 1
5: 1
6: 1
7: 1

I suppose you could have all sorts of fun with _Bool variable types, including writing functions that accept or return _Bool values. I might even use such things in my code, though I’m still apt to either use a char or short variable type as a toggle or manipulate bits directly within an int variable.

5 thoughts on “More Fun with _Bool

  1. “Given this condition, itโ€™s curious to me why the C overlords decided to create new keyworks with an underscore prefix. Itโ€™s almost like a subtle message not to use the things.”

    Maybe that’s true – perhaps the “right” way is to #include stdbool and use bool, true and false.

    When I get round to it I’ll write a set of functions to wrap using the bits of an int (for example) as booleans. It’s fiddly and messy doing it within other code so needs to be farmed out to separate functions.

    I did think of doing this in a way to allow the individual bits to be named, like in a dictionary, but realized that would use more memory than it saved!

  2. Let me know if you do that or have a post on your blog, ’cause I’d love to share it!

    I’m trying to think of a colliery for naming bits in Assembly language, but I don’t recall any. In asm, you did the same as C, either masking bits with logical operations or shifting them out. Maybe you could devise something that would become a standard?

  3. Colliery? That’s a coal mine…?

    I can read Assembly language (you can get gcc to keep the .asm files it generates as an intermediate stage which I very occasionally do if I need to figure out what’s going on) but I can’t really write it.

  4. Oh, you don’t want to write it! I toyed with Assembly ages ago and the development process is painful and slow. The results are fast code that occupies hardly any storage, but it’s not really worth it these days. Knowing what it looks like and what’s happening is good, and beneficial to understand C language concepts like pointers and bit twiddling.

  5. I’ll write it, but not in Assembly ๐Ÿ™‚

    I follow Programming Wisdom on Twitter and the other day they tweeted this:

    โ€œThe best thing about a boolean is even if you are wrong, you are only off by a bit.โ€

Leave a Reply