typedef uint8_t T_BOOL;它还值得吗?

typedef uint8_t T_BOOL; Is it still worth it?

我正在审查 C 的编码指南,我们仍然有 typedef uint8_t 布尔值的指南。我在汽车行业的一家公司工作,因此从事嵌入式软件工作,通常使用 Renesas 微处理器和 GreenHills 编译器。

我认为,由于 C99 已经推出这么多年,类型定义是多余的,我希望现代平台的所有编译器都支持 _Bool。那么,typedef 还值得吗?

奖励问题:我正在尝试整理一些 C++ 指南。我使用 C++ 的背景相对有限,但我再次认为 typedefbool 根本没有好处。我们应该使用基本的 C++ bool 类型还是应该使用自定义 typedefed T_BOOL 类型?

对于新代码,确实没有理由重新定义标准类型 - 在我们公司,我们需要 ,这意味着使用 booltruefalse,因为它阻止不同的团队和开发人员开发他们自己的(有时稍微不兼容)这些类型的变体。

对于必须处理先前声明的 bool/true/false 的旧代码,可能来自遗留框架,有时将现有类型别名(通过 typedef 或 #define)到 _Bool 中很有用。这通常是框架而非特定程序的问题。例子包括 X11 (Boolean) , Xt (_XtBoolean), ...

我认为同时包含 _Bool 和 bool 的原因是允许已经创建 'bool' 的现有代码继续工作,而不必因引入 'standard' bool 而更改代码,假与真。

在您(滥用)使用 C 提升规则将布尔值存储在除比较运算符传递的表达式类型以外的任何内容中的瞬间,即 int,您处于一种状态的罪恶。更严肃地说:我无法想象我存储布尔信息的类型会很重要,除了 大量 的布尔值,并且写了相当多的很少有汽车软件的关键任务部分,我很难想象这样的数据结构会有用的情况。几乎我曾经处理过的每条带有 yes/no 决定的信息也带有一堆相关数据,因此自然存储方案是一个结构。我从不回避位域,无论当前的 MISRA 标准对此有何看法(如果你戴着 "Sane Safety Software Expert" 的帽子仔细思考反驳,那么反对它们的案例就会化为乌有)。如果不是这种情况,它是一些全局标志,因此存储格式的大小无关紧要。所以问题是,布尔值的存储格式很重要的其余应用程序有哪些?我唯一能想到的是堆栈大小,或者更确切地说,如果您没有选择最小的可用大小,就失去了仅在寄存器中使用参数进行调用的可能性。这立即引发了两个反驳:具有许多松散耦合的布尔参数的函数非常可疑,即使它们存在,性能和内存消耗也不应该以任何方式依赖于它们(如果它们是瓶颈,那也非常可疑)。如果你有一个带有布尔值的调用层次结构,那么最大堆栈大小可能会有一个小的胜利,但这是 IME 而不是微优化的地方。

给出一个 TL;DR 答案:格式不应偏离您团队中的(新)程序员所期望的,这很可能是过去十年 use/standard 广泛使用的格式. 如果你的布尔值的存储类型真的那么重要,我完全不问,就敢远程诊断软件构造问题。

很简单:

  • 如果您使用的是标准 C,则使用 stdbool.h 中的 bool_Bool 也可以。 丑陋的 typedef 是不好的做法。
  • 如果您被迫使用旧的 C90,则必须使用某种丑陋的 typedef。

假设 C90:

布尔类型定义使用 8 位类型绝对没有坏处。 8 位类型将节省一点 RAM。可以这样做:

typedef uint8_t BOOL;
#define FALSE 0u
#define TRUE  1u

最常见的形式可能是 typedef enum { FALSE, TRUE } BOOL;

切勿全部使用小写!由于 boolfalsetrue 如果移植到标准 C 编译器将与标准冲突。

所有这些自制的形式都是不好的做法,是一种过时的 C 编写方式。没有任何借口坚持使用危险的 C90,尤其是在往往对安全至关重要的汽车系统中。

至于 MISRA-C:2012,它只是说明您应该具有某种布尔类型。它保持与 C90 的向后兼容性,因此不强制执行 bool。但是,它有很多关于如何处理布尔类型的规则,并防止将它们与各种形式的算术一起使用。


为了与 C++ 兼容,您绝对应该使用标准 C bool。该类型在设计时明确考虑了 C++ 兼容性。