我应该使用cstdint吗?

时间:2011-05-26 20:30:31

标签: c++ cstdint

我一直在思考是否应该使用<cstdint>内的typedef。

我个人更喜欢将uint32_t优先于unsigned intint8_t优先于char等...因为它对我来说更直观。

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

6 个答案:

答案 0 :(得分:35)

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

如果你想要一些肯定是32位无符号的东西,请使用uint32_t。例如,如果要实现“struct”来表示外部对象,该外部对象的规范将其中一个字段定义为32位无符号字段。

如果你想要的东西是“机器的自然字大小”,请使用int或unsigned int。例如:

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

“机器的自然字大小”将为您提供最佳性能,包括今天的处理器和未来的处理器。

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

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

答案 1 :(得分:22)

你应该同时使用两者。当您需要“合理大小”的整数时,您应该使用int,如其他答案中所述。当你需要一个角色时使用char:它是自我记录的。

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

(Endianness同样重要,但这完全是另一回事。)

答案 2 :(得分:4)

这取决于变量的用途。

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

数组

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

答案 3 :(得分:3)

您将需要使用cstdint中的typedef的一种特殊情况是在处理执行大量指针到int转换的代码时,在这种情况下使用intptr_t是绝对的要求。

在我工作的公司中,我们正在准备从32位迁移到64位吨的劣质C / C ++代码,这些代码将指针转换为int然后返回指针,这在64位架构上肯定会失败,所以我们将尽可能地尝试清理代码(即修改数据结构和接口以完全消除对转换的需要)并在其他地方使用intptr_t而不是int。

侧面说明:一般来说,施法会引起怀疑,但严重的是,指向整数的指针几乎总是你设计中某个严重缺陷的结果。基本上,每次在int后面隐藏指针时,你都会对编译器,平台以及更重要的是你的同事撒谎。

除此之外,像其他人一样说:尽可能使用泛型类型,并在需要时使用显式大小类型。

答案 4 :(得分:1)

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

只需使用typedef。

无论你是否需要unsigned int或uint32_t(你可以在以后想到,当你对程序的内容有更完整的视图时),使用typedef将通过指定什么来帮助你使代码更清晰你真的在操纵,当你想出最初的选择是最糟糕的几个月之后,它会让你更容易换到另一种类型。这里没有“正确的答案”,因为你通常会用艰难的方式解决这些问题。一些想要uint32_t的库和一些其他想要整理的库之间的互操作很痛苦。

答案 5 :(得分:-3)

尽可能使用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;
}

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

您可以专门化模板化的函数或类,优化特定情况或使用不符合相关接口的类(或C 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;
}