我应该用cstilt吗

Should I use cstdint?

本文关键字:cstilt 我应该      更新时间:2023-10-16

我一直在考虑是否应该在<cstdint>中使用typedefs。

我个人更喜欢写uint32_t而不是unsigned int,写int8_t而不是char等等……因为对我来说,这要直观得多。

你们觉得怎么样?是否使用<cstdint>中的typedefs是个好主意?有什么缺点吗?

实际上,我建议两者都使用。

如果您想要的东西肯定是32位无符号的,请使用uint32_t。例如,如果您正在实现一个"结构"来表示一个外部对象,该对象的规范将其一个字段定义为32位无符号字段。

如果你想要的东西是"机器的自然字大小",使用int或无符号int。例如:

for (int i = 0 ; i < 200 ; ++i)
    // stuff

"机器的自然字大小"将为您提供最佳性能,无论是在今天的处理器上还是在明天的处理器上。

如果您的意思是"字符",请使用"字符";"char"或"unsigned char",如果您的意思是"byte"。严格来说,C/C++允许您通过"char*"访问任意对象的字节,而不是其他任何东西。

如果您特别想要一个8位整数,请使用uint8_t或int8_t,类似于uint32_t。

两者都应该使用。当您需要一个"大小合理"的整数时,您应该使用int,正如其他答案中所解释的那样。当您需要一个字符时,请使用char:它是自记录的。

当你用二进制与外部世界接口时,你应该使用uint32_t和朋友:当你进行网络编程、处理二进制文件或使用外部多字节编码时,等等。在这些情况下,类型的确切大小对于编写正确、可移植、自文档化的代码至关重要。这就是<stdint.h>(或C++0x <cstdint>)的作用。

(持久性同样重要,但那完全是另一回事。)

这取决于变量的用途。

如果需要循环计数器,请使用int。如果需要字符串,请使用char数组。

如果您需要一个可以容纳-1到100的数字变量,那么int8_t就很好了。如果您需要表示0到100000之间的值,则uint32_tuint_least32_t(感谢@Serge)是一个很好的选择。

在一种特殊情况下,需要使用cstilt中的typedefs,这是在处理大量指针到int转换的代码时,在这种情况下,使用intptr_t是绝对需要的。

在我工作的公司,我们正准备从32位迁移到64位,大量质量较差的C/C++代码不断将指针转换为int,然后再转换回指针,这在64位架构上肯定会失败,因此,我们将尽可能地对代码进行清理(即修改数据结构和接口以完全消除对强制转换的需要),并在其他任何地方使用intptrt而不是int。

顺便说一句:一般情况下,强制转换应该引起怀疑,但说真的,将指针强制转换为整数几乎总是设计中某个严重缺陷的结果。基本上,每次在int后面隐藏指针时,你都是在对编译器、平台撒谎,更重要的是对你的同事撒谎

除此之外,正如其他人所说:尽可能使用泛型类型,必要时使用显式大小的类型。

您基本上似乎对uint32_t和unsigned int之间没有任何线索。这是完全正常的,因为您不一定知道以后将如何使用您的类型。

只需使用typedef

不管你需要一个无符号的int还是uint32_t(你可以稍后考虑,当你对程序有了更完整的了解时),使用typedef将通过指定你真正操作的内容来帮助你使代码更清晰,并且当你发现几个月后你的初始选择是最糟糕的时,它将使你更容易更改为另一种类型。这里没有一个"正确的答案",因为你通常很难解决这些问题。一些想要uint32_t的库和另一些想要int的库之间的交互是痛苦的。

尽可能使用template和通用编程。如果不需要的话,不要依赖任何类型!

如果你有一个函数,它取一个数字并将其乘以2,那么就这样写:

template <typename Number>
inline Number doubleNum(Number n) {
  return 2*n;
}

甚至这个:

template <typename RetType, typename NumberType>
inline RetType doubleNum(NumberType n) {
  return 2*n;
}

这样,如果您有一个使用ints、doubles和uint64_ts的库,您可以使用它,而无需重写代码。如果您需要使用二进制文件或网络编程,您可以使用固定大小的类型,而无需重写代码。如果您需要任意精度的数字,您可以使用一个类,该类通过运算符重载实现与基元整数或浮点类型相同的接口,例如GMP包装器,而无需重写代码

您可以专门化模板化的函数或类,以优化特定的情况,或者处理不符合相关接口的类(或struct):

/*
 * optimization:
 * primitive integers can be bit-shifted left to
 * achieve multiplication by powers of 2
 * (note that any decent compiler will do this
 *  for you, behind the hood.)
 */
template <>
inline int doubleNum<int>(int n) {
  return n<<1;
}
/*
 * optimization:
 * use assembly code
 */
template <>
inline int32_t doubleNum<int32_t>(int32_t n) {
  asm {
    ...
  }
}
/*
 * work with awkward number class
 */
template <>
inline AwkwardNumber doubleNum<AwkwardNumber>(AwkwardNumber n) {
  n.multiplyBy(2);
  return n;
}