Почему основные компиляторы используют typedef для stdint.h, но используют #define для stdbool.h?

Я только заметил, что gcc и clang оба, похоже, используют typedefs для stdint.h, но #define для stdbool.h.

Пример: clang stdint.h

 #ifdef __INT8_TYPE__
 #ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
 typedef __INT8_TYPE__ int8_t;
 #endif /* __int8_t_defined */
 typedef __UINT8_TYPE__ uint8_t;
 # define __int_least8_t int8_t
 # define __uint_least8_t uint8_t
 #endif /* __INT8_TYPE__ */

clang stdbool.h

#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool, bool, false, true as a GNU extension. */
#define _Bool bool
#define bool  bool
#define false false
#define true  true
#endif

Почему это не typedef _Bool bool;?

(gcc stdint.h и stdbool.h)

Ответ 1

stdbool.h определяет bool как макрос, поскольку стандарт C (раздел 7.18) говорит, что bool определяется как макрос, и stdint.h определяет intN_t и т.д. как typedefs, потому что стандарт C (раздел 7.20) говорит, что intN_t и т.д. должны быть определены как typedefs.

Хорошо, почему стандарт C говорит об этом? Я не могу вам точно сказать, но в разделе 7.18 параграфа 4 есть ключ:

Несмотря на положения 7.1.3, программа может определить неопределенность и, возможно, затем переопределить макросы bool, true и false.

Если bool были typedef и true и false были, я не знаю, enum константы, они не могли бы позволить вам сделать это, так как нет возможности отменить эти виды объявлений.

Хорошо, почему комитет C хочет позволить вам сделать это? Это еще более спекулятивно, но, вероятно, по той же причине они добавили stdbool.h и _Bool вместо создания ключевых слов bool, true и false, как они есть на С++: они хотели сохранить совместимость со старыми программы, которые сами определяли bool, true и false, даже если эти программы используют сторонние заголовки, которые включают stdbool.h...

Никакая такая обратная совместимость не относится к типам, определенным stdint.h; некоторые системы предоставляли (некоторые) из них как расширения, но они всегда были typedefs.

Ответ 2

Я думаю, что это всего лишь часть стандарт.

Если вы перейдете на страницу 253, под "7.16 Булевы тип и значения" , он четко говорит:

1) Заголовок <stdbool.h> определяет четыре макроса.

2) Макрос

bool

расширяется до _Bool.