105

stdint.h和 和有什么不一样cstdint

它们都在 MSVC (Visual Studio 2010) 和 gcc-4.5.1 中可用。还都定义了intX_t/uintX_t类型(其中类型X的大小以字节为单位)。

  • 如果两个标题中的基本原理相同(便携式类型),我必须做出哪些决定来决定其中一个?

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

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

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

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

3 回答 3

133

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

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

  • 使用<cstdint>并完全限定您使用的每个整数类型,或者使用using std::int32_t;etc 将其带入范围(烦人,因为冗长,但它是正确的方法,就像 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++ 全局命名空间中并不是一个完全愚蠢的想法,但这并不是必需的。

于 2012-11-30T10:08:03.087 回答
17

包括cstdint在 std 命名空间和可能在全局命名空间中导入符号名称。
包括在全局命名空间和可能在 std 命名空间stdint.h中导入符号名称。

C 标准库的功能也在 C++ 标准库中提供,并且作为一般命名约定,它们在 C 标准库中的相应名称前加上 c。

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

#include <cstdint>

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

#include <stdint.h>

附件 D(规范性)兼容性特性 [depr]规定:

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 中提供这些名称。—结束示例]

于 2012-11-30T10:03:08.900 回答
0
  1. cstdint是 C++11 头文件,stdint.h是 C99 头文件(C 和 C++ 是不同的语言!)

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

  3. 的实现cstdint大多只是简单地#include <stdint.h>修复了一些命名空间/语言。

于 2012-11-30T10:03:59.773 回答