10

I was hoping somebody could explain why

#include <stdbool.h>

printf("size of bool %d\n", sizeof(bool));
printf("size of int %d\n", sizeof(int));

outputs to

size of bool 1
size of int 4

I've looked at http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html which seems to indicate that bool is essentially a macro for _Bool which, when set to true or false, is really just a macro for an integer constant. If it is an integer, why is it not the same size?

I'm asking because it took us far too long to debug a program for which we did not allocate enough memory.

7
  • 2
    Just curious — if a bool is smaller than you expected, how did you not allocate enough memory? Commented May 17, 2012 at 5:10
  • @detly Well, to be honest we aren't sure. We had an array of bool that always resulted in a segmentation fault until we multiplied the malloc(x*sizeof(bool)) by malloc(4*x*sizeof(bool)) It could have been something completely different, but that solved the problem and led me to this question. Commented May 17, 2012 at 5:15
  • 4
    You were declaring triple pointers - at what level were you allocating x*sizeof(bool)? For the first two levels, which are pointers-to-pointers, you would have to allocate sizeof(bool*) because sizeof(bool*) is likely not equal to sizeof(bool). Commented May 17, 2012 at 5:33
  • 1
    @birrtree That is very interesting. We were allocationg x*sizeof(bool) for every level. But now that you mention it, (and I sit and think about it) we would need to allocate memory for the pointer and not the actual bool for all levels except the last. Wow! As I mentioned in your answer, this has been very educational and helpful! Commented May 17, 2012 at 5:43
  • 1
    Yep, for the first two levels, since they will be pointers to pointers, you have to allocate space to store pointers, so use something like x*sizeof(bool*) instead of x*sizeof(bool). This way you won't have to do something like 4*x*sizeof(bool), because that would only help you on systems where pointers are 4-bytes wide (32-bit programs). In a 64-bit program, you'd run into memory crashes again. sizeof(bool*) will work correctly on either 32-bit or 64-bit. Commented May 17, 2012 at 6:14

6 Answers 6

18

The _Bool type in C99 (typedef'ed to bool in stdbool.h) doesn't have a standard defined size, but according to section 6.2.5 of the C99 Standard:

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

In C, the smallest addressable object (aside from bitfields) is the char, which is at least 8-bits wide, and sizeof(char) is always 1.

_Bool and bool therefore have a sizeof of at least 1, and in most implementations that I've seen, sizeof(bool) / sizeof(_Bool) is 1.

If you take a look at GCC's stdbool.h, you'll get this:

 #define bool    _Bool
 #if __STDC_VERSION__ < 199901L && __GNUC__ < 3
 typedef int _Bool;
 #endif

 #define false   0
 #define true    1

So if using an older version of GCC and an old version of the C standard when compiling, you will use int as a _Bool type.

Of course, as an interesting thing, check this out:

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

int main() {
   printf("%zu\n", sizeof(_Bool));
   printf("%zu\n", sizeof(true));
   printf("%zu\n", sizeof(false));

}

Output:

λ > ./a.out 
1
4
4

GCC 4.2.4, Clang 3.0, and GCC 4.7.0 all output the same. As trinithis points out, sizeof(true) and sizeof(false) produce larger sizes because they are taking the size of an int literal, which is at least sizeof(int).

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for the answer. I'm still beginning with C and I've learned much more from your reply than just the answer to the question.
The sizeof makes sense because they are #defines for int literals. Sizeof an int literal is sizeof int. true and false are int literals in this case.
@trinithis - yeah, just wanted to draw attention to the different sizeofs you'd get if you tried it against the type vs. the other macros provided by the header.
Just as a nitpick, the correct printf format for size_t is z, here %zu would do the trick.
Thanks @JensGustedt - edited to reflect the correct modifier.
3

The C99 Standard introduced the _Bool type. _Bool is guaranteed to be big enough to hold integer constants 0 or 1, this does not necessarily mean it is an int. The actual size is compiler dependent.

Comments

2

It is an integer, but not an int. char, short, int, long, long long, etc., are all integers. char is guaranteed to have a size of 1. The rest are at least as large as char (and it's hard to imagine how you'd make the I/O system work correctly if int wasn't larger than char). There's also a required order from char to long long (same order I listed them above) where each type must have at least as much range as its predecessors.

Other than that, however, you're not guaranteed much about sizes of integer types. Specifically, char is the only one of the "base" types that has a guaranteed size (though there are types like int8_t and int32_t that have guaranteed sizes).

Comments

2

I am pretty sure it is dependent on your compiler, perhaps yours is using byte instead of int for bool? Either way you shouldn't have memory allocation problems if you use sizeof() to know how much memory to allocate, for example, if you want to allocate 10 bools worth of memory, don't allocate 10 * 4, do 10 * sizeof(bool) so you can't go wrong.

Comments

1

As I know from porting code from Windows to Unix you can never be sure about the size of a datatype. It depends on the operating system and sometimes even on the compiler you use.

The specifications of stdbool.h only say that TRUE and FALSE are mapped to an integer (1 and 0). This does't mean that the datatype bool is of type int. From my experience bool is of the smallest datatype available (i.e char or byte):

bool flag = TRUE; -> byte flag = 0x01;

In eclipse CDT and Visual Studio you can follow the macro definitions in order to see what really lies behind your datatypes.

So I would suggest you always ask your compiler about the memory space needed in order to allocate enough memory (This is also what I saw in a lot of libraries):

malloc(4*sizeof(bool));

I hope this helps.

1 Comment

Interesting. I didn't know you could follow macro definitions in eclipse. It's always nice to learn much more than just the answer to the original question!
0

The _Bool is native to the compiler, is defined in C99 and may be activated like gcc -std=c99; stdbool.h #define bool to be _Bool, and true and false to simply int literals that pretty well fit into that _Bool.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.