繁体   English   中英

<cstdint>对比<stdint.h></stdint.h></cstdint>

[英]<cstdint> vs <stdint.h>

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扩展名。

  • 此标头的命名约定是什么? c前缀表示这是一个 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++-only 符号。 C 标准中有一节列出了为将来添加到标准中而保留的名称。 将这些名称也视为 C++ 全局名称空间中的保留名称并不是一个完全愚蠢的想法,但这不是必需的。

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

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

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

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

  3. cstdint的实现主要是简单的#include <stdint.h>和一些命名空间/语言修复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM