<cstdint> vs <stdint.h>

<cstdint> vs <stdint.h>

本文关键字:gt lt stdint cstdint vs      更新时间:2023-10-16

stdint.hcstdint之间有什么区别?

它们都可以在MSVC(Visual Studio 2010)和gcc-4.5.1中使用。此外,两者都定义了intX_t/uintX_t类型(其中X是以位为单位的类型的大小)。

  • 如果两个标头中的基本原理相同(可移植类型),那么我必须做出哪些决定才能决定其中一个

stdint.h定义了每个没有任何命名空间的类型,cstdint类型位于std命名空间中。

  • 是否有任何理由将已定义的类型包括或不包括在std命名空间中?这两个标题之间有什么不同

cstdint没有文件扩展名,使用c前缀,stdint.h使用.h扩展名。

  • 此标头的命名约定是什么?CCD_ 14前缀表示这是一个C库?cstdint中缺少文件扩展名是有原因的吗

C++98中的初衷是应该在C++中使用<cstdint>,以避免污染全局命名空间(好吧,不是特别的<cstdint>,它只在C++11中添加,但通常是<c*>标头)。

然而,无论如何,实现都坚持将符号放入全局命名空间,并且C++11批准了这种做法[*]。所以,你基本上有三个选择:

  • 使用<cstdint>并完全限定您使用的每个整数类型,或者使用using std::int32_t;等将其纳入范围(这很烦人,因为很冗长,但这是正确的方法,就像C++标准库中的任何其他符号一样)
  • 使用<stdint.h>(有点糟糕,因为已弃用)
  • 使用<cstdint>并假设您的实现将把符号放在全局命名空间中(非常糟糕,因为不能保证)

在实践中,我怀疑大量令人讨厌的代码使用了最后一个选项,只是因为在<cstdint>将符号放在全局命名空间中的实现中,这很容易意外。你应该试着使用第一个。第二个优点是,可以保证将东西放入全局命名空间,而不是仅仅这样做。我认为这不是特别有用,但如果这是你的优先事项,它可能会节省一些类型。

还有第四个选项,#include <cstdint>后面跟着using namespace std;,这有时很有用,但有些地方不应该放using namespace std;。不同的人会对这些地方有不同的想法,但"在头文件中的顶级"比"在cpp文件中的高级"更糟糕,后者比"在有限的范围内"更糟糕。有些人根本不写using namespace std;

[*]这意味着C++标准头可以将内容放在全局命名空间中,但不是必须的。因此,你必须避免与这些符号发生冲突,但你不能实际使用它们,因为它们可能不在那里。基本上,C++中的全局命名空间是一个雷区,尽量避免它。有人可能会说,委员会已经批准了一种通过实现的做法,这种做法几乎与将using namespace std;粘贴在头文件的顶层一样有害——不同的是,实现只对C标准库中的符号执行,而using namespace std;也对仅C++的符号执行。C标准中有一节列出了为将来添加到该标准中而保留的名称。将这些名称也视为C++全局命名空间中的保留名称并不是一个完全愚蠢的想法,但这并不重要。

包含cstdint将导入std命名空间中的符号名称,并可能导入Global命名空间中的
包括stdint.h将导入Global命名空间中的符号名称,可能导入std命名空间中的

C++标准库中还提供了C标准库的特性,作为通用命名约定,它们由C附加到C标准库中的相应名称。

在C++中,您应该使用:

#include <cstdint>

并完全限定您与std::
一起使用的符号名称,而在C中,您应该使用:

#include <stdint.h>

附件D(标准)兼容性特征[dep]状态:

D.6 C标准库头

1为了与C标准库和C Unicode TR兼容,C++标准库提供了25个C头,如表151所示。

其中包括:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h><complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h><ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h><errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h><fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

此外,

2每个C标头的名称形式为name.h,其行为就好像由相应的cname header放置在标准库命名空间中的每个名称都放置在全局命名空间范围内未指定这些名称是否首先在命名空间std的命名空间范围(3.3.6)中声明或定义,然后通过显式使用声明(7.3.3)注入全局命名空间范围。

3[示例:标头<cstdlib>肯定会在命名空间std中提供其声明和定义。它也可以在全局命名空间中提供这些名称。标头<stdlib.h>肯定会在全局命名空间内提供相同的声明和定义,就像在C标准中一样。它也可能在命名空间std-结束示例]

  1. cstdint是C++11标头,stdint.h是C99标头(C和C++是不同的语言!)

  2. MSVC 2008既不包含stdint.h也不包含cstdint

  3. cstdint的实现大多是简单的#include <stdint.h>,带有一些名称空间/语言修复。