Я пытался написать несколько макросов для безопасного использования типа _Bool
, а затем стресс-тестировать мой код. Для злых целей тестирования я придумал этот грязный хак:
_Bool b=0;
*(unsigned char*)&b = 42;
Учитывая, что _Bool
составляет 1 байт в реализации sizeof(_Bool)==1
), я не вижу, как этот хак нарушает стандарт Си. Это не должно быть строгое нарушение псевдонимов.
Тем не менее, при запуске этой программы через различные компиляторы у меня возникают проблемы:
#include <stdio.h>
int main(void)
{
_Static_assert(sizeof(_Bool)==1, "_Bool is not 1 byte");
_Bool b=0;
*(unsigned char*)&b = 42;
printf("%d ", b);
printf("%d", b!=0 );
return 0;
}
(Код основан на printf
неявном повышении аргумента по умолчанию до int
)
Некоторые версии gcc и clang выдают 42 42
, другие - 0 0
. Даже с отключенной оптимизацией. Я бы ожидал 42 1
.
Казалось бы, компиляторы предполагают, что _Bool
может быть только 1
или 0
, но в то же время он счастливо печатает 42
в первом случае.
Q1: Почему это? Содержит ли приведенный выше код неопределенное поведение?
Q2: Насколько надежен sizeof(_Bool)
? C17 6.5.3.4 вообще не упоминает _Bool
.