Вывод bool в printf
Есть переменная:
bool x = true;
Хочу её загнать в printf в виде числа. Очевидно, что можно сделать
printf("%d", (int)x);
но кастить тип как-то лень и хочется сделать что-то такое:
printf("%hhu", x);
Это тоже работает поскольку с unsigned char и bool занимают по 1 байту, но разрешает ли стандарт такой вывод?
Ответы (1 шт):
Неизвестные аргументы, передаваемые в вариативную функцию подвергаются расширению аргументов по-умолчанию (default argument promotions). Суть его в следующем:
- типы с плавающей точкой подвергаются расширению типов с плавающей точкой (floating-point promotion),
- Целочисленные типы и типы перечисления подвергаются целочисленному расширению (integral promotions)
[...] If the argument has integral or enumeration type that is subject to the integral promotions, or a floating-point type that is subject to the floating-point promotion, the value of the argument is converted to the promoted type before the call. These promotions are referred to as the default argument promotions.
При расширении типов с плавающей точкой значение типа float преобразуется к значению типа double. conv.fpprom/1:
A prvalue of type
floatcan be converted to a prvalue of typedouble. The value is unchanged.
Описание процесса целочисленного расширения довольно объёмно, см.: conv.prom.
Но что касается типа bool, то он при целочисленном расширении преобразуется к типу int, причём значение false преобразуется в 0, а значение true преобразуется в 1. conv.prom/6:
A prvalue of type
boolcan be converted to a prvalue of typeint, withfalsebecoming zero andtruebecoming one.
Таким образом, значение типа bool, передаваемое в функцию std::printf, перед вызовом преобразуется в значение типа int. А значит его можно вывести так:
bool x = true;
printf("%d", x);
Разберём печать bool с помощью %hhu
Спецификатор преобразования %hhu говорит, что функция printf ожидает получить значение типа unsigned int, которое она перед выводом преобразует в значение типа unsigned char. Так как тип фактически передаваемого аргумента не соответствует спецификатору преобразования (bool расширяется до int)
bool x = true;
printf("%hhu", x);
то поведение программы не определено.
N1570, 7.21.6.1/9:
[...] If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
P.S.
Стандарт языка не гарантирует, что тип bool занимает один байт. expr.sizeof/1:
[Note 1: In particular, the values of
sizeof(bool),sizeof(char16_t),sizeof(char32_t), andsizeof(wchar_t)are implementation-defined.65 — end note]
sizeof(bool)is not required to be1.