Richard Hansen
Richard Hansen

Reputation: 54223

Is there a 'printf' conversion specifier for _Bool?

With printf(), I can use %hhu for unsigned char, %hi for a short int, %zu for a size_t, %tx for a ptrdiff_t, etc.

What conversion format specifier do I use for a _Bool? Does one exist in the standard?

Or do I have to cast it like this:

_Bool foo = 1;
printf("foo: %i\n", (int)foo);

Upvotes: 14

Views: 20332

Answers (5)

Stephanie G
Stephanie G

Reputation: 1

I use %b for a Java printf() conversion specifier. I tried it recently and to my surprise it worked.

Here is the line of code:

System.out.printf("firstRobot == secondRobot: %b",firstRobot == secondRobot);

Here is the output:

firstRobot == secondRobot: false

Upvotes: 0

tomlogic
tomlogic

Reputation: 11694

As you stated in a comment to @Jack, "6.3.1.1p1 says that the conversion rank of _Bool is less than the rank of all other standard integer types".

In a call to printf, a char or short will be promoted and passed on the stack as an int (or an unsigned int), so I would think that using %d as a format specifier would be fine. That also means that you don't need the explicit cast to int, because that will happen automatically.

The only possible issue would be with how the compiler represents a _Bool, something that it probably implementation defined and could vary from one compiler to another. I see two likely implementations -- 0 and 1 or 0 and -1.

For the ultimate in portability, follow @user325181's answer and use a ternary to choose between two options. Either integers (which the compiler may optimize away) or strings.

Edit: As reported in other answers, a _Bool is defined as an unsigned integral type that can store either 0 or 1. Because of that, and the fact that it will be promoted to an unsignedint when passed to printf(), I would say that %u%d is the most appropriate specifier.

Upvotes: 2

Jack
Jack

Reputation: 16724

There is no. Just handling it like an int by using %d or %i specifier.

_Bool

In C99, a new keyword, _Bool, is introduced as the new boolean type. In many aspects, it behaves much like an unsigned int, but conversions from other integer types or pointers always constrained to 0 and 1. Other than for other unsigned types, and as one would expect for a boolean type, such a conversion is 0 if and only if the expression in question evaluates to 0 and it is 1 in all other cases. The header stdbool.h provides macros bool, true and false that are defined as _Bool, 1 and 0, respectively.

The first way to implement it that come from into mind is by using a char or(int8_t) an enum and with bit fields. But actually, it depends. It can be a typedef for an int(as I've mentioned, it's used, but is not recommend, subject to bugs) or char or unsigned int or an enum and #define that's commonly used.

For exampe, Apple's implementation uses int,as you can see:

#ifndef _STDBOOL_H_
#define _STDBOOL_H_ 

#define __bool_true_false_are_defined   1

#ifndef __cplusplus

#define false   0
#define true    1

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

#endif /* !__cplusplus */

#endif /* !_STDBOOL_H_ */

Others implementations:

typedef int8_t _Bool;

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

typedef unsigned char Boolean; typedef _Bool Boolean;

Upvotes: 1

ouah
ouah

Reputation: 145899

There is no specific conversion length modifier for _Bool type.

_Bool is an unsigned integer type large enough to store the values 0 and 1. You can print a _Bool this way:

_Bool b = 1;
printf("%d\n", b);

Because of the integer promotions rules, _Bool is guaranteed to promote to int.

Upvotes: 13

Clarus
Clarus

Reputation: 2338

Until C99, bool was not apart of standard C, and thus did not exist as a printf modifier. C99, defined _Bool (which you are using) to be an integer, thus you should be fine casting it as an integer to display (at least from a machine perspective). Alternatively, you could do something like:

printf("%d",foo?1:0);

Upvotes: 6

Related Questions