<cstdint> vs <stdint.h> </stdint.h> </cstdint>

时间:2012-11-30 09:58:57

标签: c++ stdint cstdint

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中缺少文件扩展名的原因是什么?

3 个答案:

答案 0 :(得分:102)

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 ++全局命名空间中保留的并不是一个完全愚蠢的想法,但它并不是必需的。

答案 1 :(得分:14)

包括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中提供这些名称。 - 例子]

答案 2 :(得分:0)

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

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

  3. cstdint的实现大多只是#include <stdint.h>,其中包含一些命名空间/语言修复。