<cstdint>与<stdint.h>


94

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

OS X 10.8缺乏<cstdint>。这是我收到的错误:./misc.h:7:10: fatal error: 'cstdint' file not found
jww

Answers:


122

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 ++全局命名空间中保留也不是一个完全愚蠢的主意,但这不是必需的。


剩下的唯一未解决的问题是有关头文件的命名约定,您知道这一主题吗?
PaperBirdMaster 2012年

24
@PaperBirdMaster:C ++标准库头不具有文件扩展名:<iostream><vector><cstdlib>,除了包括为C兼容性的那些:<stdint.h><stdlib.h>。是的,首字母c表示<cstdlib>C ++等同于C标准头文件<stdlib.h>,而不是像原来那样对C ++来说<vector>是全新的。有一个C ++标头<complex>,因此我们只希望将来的C版本不会引入标准标头<omplex.h>
史蒂夫·杰索普

@SteveJessop Erm,C99?
SS安妮

1
@ JL2210注意他说的<omplex.h>不是<complex.h>。如果添加C <omplex.h>,则C ++等效为<complex>
John Leuenhagen

16

包括cstdint在std命名空间以及可能在Global命名空间中导入符号名称。
包括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)中首先声明还是定义的,然后通过显式using-声明(7.3.3)注入到全局名称空间范围中。

3 [示例:标头<cstdlib>肯定会在名称空间std中提供其声明和定义。它还可以在全局名称空间中提供这些名称。该标头<stdlib.h>肯定会在全局命名空间中提供与C标准中相同的声明和定义。它还可以在名称空间std中提供这些名称。—结束示例]


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

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

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


2
3.错了。cstdint需要将实现提升到名称空间中std
康拉德·鲁道夫2012年

1
1.同样也是错误的,stdint.h在C ++标准的规范附录D中定义为C ++库的一部分。
2012年

@chill,能否请您提供附件D的链接?此处en.cppreference.com/w/cpp/types/integer表示这是C ++ 11标头。
hate-engine

1
@ hate-engine,建议您在C ++标准的副本中查找它。该cppreference页面未提及stdint.h。没有参数cstdint是C ++标头。
寒意

2
1.的任何部分都不为假,只是看起来像您所说stdint.h的不是C ++ 11的一部分。实际上,这是C ++ 11所必需的。您可能会说:“ int在C ++ 11中;long在C99中; C和C ++是不同的语言!”,并且其中的任何部分都不是错误的。我的例子更是误导,不过,因为C ++ 11是指在部分C99定义两者的内容stdint.hcstdint,但不是指C中定义int
史蒂夫·杰索普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.