【问题标题】:Best Practices: Should I create a typedef for byte in C or C++?最佳实践:我应该在 C 或 C++ 中为字节创建 typedef 吗?
【发布时间】:2010-11-27 09:57:43
【问题描述】:

您更喜欢在代码中看到t_byte*(带有typedef unsigned char t_byte)或unsigned char* 之类的东西吗?

我在自己的库中倾向于使用t_byte,但从未参与过采用这种方法的大型项目,我想知道其中的陷阱。

【问题讨论】:

    标签: c++ c pointers typedef


    【解决方案1】:

    如果您使用的是 C99 或更新版本,则应为此使用 stdint.huint8_t,在这种情况下。

    C++ 直到 C++11 才得到这个头文件,称之为cstdint。旧版本的 Visual C++ 不允许您在 C++ 代码中使用 C99 的 stdint.h,但几乎所有其他 C++98 编译器都允许,因此即使使用旧编译器,您也可以选择。

    与许多其他事情一样,Boost 解决了 boost/integer.hpp 中的这种差异,如果您的编译器的标准 C++ 库没有,则提供类似 uint8_t 的内容。

    【讨论】:

      【解决方案2】:

      我建议如果您的编译器支持它,请使用 C99 <stdint.h> 标头类型,例如 uint8_tint8_t

      如果您的编译器不支持它,请创建一个。 Here'sVC++ 的示例,旧版本没有 stdint.hGCC 确实支持stdint.h,而且确实大部分C99

      您的建议的一个问题是char 的符号是实现定义的,所以如果您确实创建了一个类型别名。您至少应该明确说明该标志。这个想法有一些优点,因为在 C# 中,例如 char 是 16 位的。但它也有字节类型。


      补充说明...

      你的建议没有问题,你确实指定了无符号。

      如果数据实际上是字符数据,我还建议使用纯 char,即是纯文本的表示,例如您可能在控制台上显示的。在使用标准库和第三方库时,这将减少类型一致性问题。另一方面,如果数据表示非字符实体(例如位图),或者如果它是您可以对其执行算术操作的数字“小整数”数据,或者您将对其执行逻辑操作的数据,则其中一个应该使用stdint.h 类型(甚至是从其中之一定义的类型)。

      我最近发现了一个 TI C54xx 编译器,其中 char 实际上是 16 位的,所以这就是为什么尽可能使用 stdint.h,即使你使用它来定义 byte 类型比假设 unsigned char 是一个合适的别名更可取。

      【讨论】:

      • 关于我的例子的好点,我将沃伦的答案标记为正确,因为他是第一个而且他的帖子很简洁。至少为你点赞...
      【解决方案3】:

      我更喜欢类型来传达存储在其中的值的含义。如果我需要一种类型来描述我机器上的字节,我更喜欢byte_t 而不是unsigned char,这可能意味着任何事情。 (我一直在使用signed charunsigned char 来存储UTF-8 字符串的代码库中工作。)uint8_t 也是如此。它可以这样使用:一个 8 位无符号整数。

      使用byte_t(与任何其他恰当命名的类型一样),很少需要查找它的定义(如果是这样,一个好的编辑器将花费 3 秒时间为您查找它;也许10 秒,如果代码库很大),只需查看它就可以清楚地知道存储在该类型对象中的内容。

      【讨论】:

        【解决方案4】:

        我个人更喜欢boost::int8_tboost::uint8_t

        如果您不想使用 boost,可以借用 boost\cstdint.hpp

        另一种选择是使用portable version of stdint.h(来自this 答案的链接)。

        【讨论】:

        • 我真的不喜欢只为 typedef 需要一个 boost 标头。
        • 请注意,虽然 stdint.h 由 C99 定义,但当前 ISO C++ 标准没有 要求(因为它早于 C99),因此您可能会在某些编译器中发现必须使用标头名称的 C 约定是使用 stdint 类型,这将是最便携的形式。
        【解决方案5】:

        除了您笨拙的命名约定之外,我认为这可能还可以。请记住,boost 会为您执行此操作,以帮助实现跨平台能力:

        #include <boost/integer.hpp>
        
        typedef boost::uint8_t byte_t;
        

        请注意,通常类型的后缀是_t,如byte_t

        【讨论】:

        • 您定义的类型不应以“_t”为后缀,因为此类名称是为语言和标准库的扩展保留的(例如,添加 uint8_t 不会破坏大量现有代码)。
        • @chrisharris 你在哪里找到这个信息的?我正在查看 ISO C++ 标准的草稿,但找不到该部分,但我有一位同事喜欢以这种方式为他的所有类/函数模板添加后缀,并想向他指出。跨度>
        • @stinky472:我不知道 ISO C 标准对此有何规定,但常识认为自定义名称不应与标准名称冲突,因此为避免麻烦,最好使用 byte。或者,如果您的同事愿意,请使用 前缀 而不是后缀:t_byte.
        【解决方案6】:

        我更喜欢使用标准类型、unsigned char、uint8_t 等,因此任何查看源代码的程序员都不必再参考标题来理解代码。您使用的 typedef 越多,其他人了解您的打字约定所需的时间就越多。对于结构,绝对使用 typedef,但对于基元,请谨慎使用。

        【讨论】:

          猜你喜欢
          • 2015-09-25
          • 2017-03-27
          • 1970-01-01
          • 2023-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-06
          相关资源
          最近更新 更多