简体   繁体   English

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

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

What is the difference between stdint.h and cstdint ? stdint.hcstdint什么区别?

Both of them are available in MSVC (Visual Studio 2010) and gcc-4.5.1.它们都在 MSVC (Visual Studio 2010) 和 gcc-4.5.1 中可用。 Also both define the intX_t / uintX_t types (where X is the size in bytes of the type).还都定义了intX_t / uintX_t类型(其中X是该类型的字节大小)。

  • If the rationale in both headers is the same (portable types), what decisions I must take to decide on one or the other?如果两个标头中的基本原理相同(便携式类型),我必须做出什么决定来决定一个或另一个?

The stdint.h defines each type without any namespace, the cstdint types lies in the std namespace. stdint.h定义了没有任何命名空间的每个类型, cstdint类型位于std命名空间中。

  • Is there any reason to include or to not include the defined types into the std namespace?是否有任何理由将定义的类型包含或不包含到std命名空间中? What is different between the two headers?这两个标题有什么不同?

cstdint has no file extension and uses the c prefix, stdint.h uses the .h extension. cstdint没有文件扩展名并使用c前缀, stdint.h使用.h扩展名。

  • What are the naming conventions for this headers?此标头的命名约定是什么? the c prefix indicates that this is a C library? c前缀表示这是一个 C 库? there's a reason for the lack of file extension in cstdint ? cstdint中缺少文件扩展名是有原因的吗?

The original intention in C++98 was that you should use <cstdint> in C++, to avoid polluting the global namespace (well, not <cstdint> in particular, that's only added in C++11, but the <c*> headers in general). C++98 的初衷是你应该在 C++ 中使用<cstdint> ,以避免污染全局命名空间(好吧,特别不是<cstdint> ,它只在 C++11 中添加,但是<c*>一般标题)。

However, implementations persisted in putting the symbols into the global namespace anyway, and C++11 ratified this practice[*].然而,无论如何,实现坚持将符号放入全局命名空间,并且 C++11 批准了这种做法[*]。 So, you basically have three options:所以,你基本上有三个选择:

  • Use <cstdint> and either fully qualify each integer type you use or else bring it into scope with using std::int32_t;使用<cstdint>并完全限定您使用的每个整数类型,或者using std::int32_t; etc (annoying because verbose, but it's the right way to do it just like for any other symbol in the C++ standard library)等等(烦人,因为冗长,但这是正确的方法,就像 C++ 标准库中的任何其他符号一样)
  • Use <stdint.h> (slightly bad because deprecated)使用<stdint.h> (有点不好,因为不推荐使用)
  • Use <cstdint> and assume your implementation will put the symbols in the global namespace (very bad because not guaranteed).使用<cstdint>并假设您的实现会将符号放在全局命名空间中(非常糟糕,因为无法保证)。

In practice I suspect that an annoying large amount of code uses the last option, simply because it's easy to do by accident on an implementation where <cstdint> puts the symbols in the global namespace.在实践中,我怀疑大量烦人的代码使用了最后一个选项,仅仅是因为在<cstdint>将符号放入全局命名空间的实现中很容易意外地这样做。 You should try to use the first.你应该尝试使用第一个。 The second has one virtue, that it is guaranteed to put stuff in the global namespace instead of only maybe doing it.第二个有一个优点,它保证将东西放在全局名称空间中,而不是仅仅可能这样做。 I don't think that's particularly useful, but it might save some typing if that's your priority.我认为这不是特别有用,但如果这是您的首要任务,它可能会节省一些打字时间。

There's a fourth option, #include <cstdint> followed by using namespace std;还有第四个选项, #include <cstdint>后跟using namespace std; which is sometimes useful but there are places that you shouldn't put the using namespace std;这有时很有用,但有些地方你不应该把using namespace std; . . Different people will have different ideas where those places are, but "at top level in a header file" is worse than "at top level in a cpp file", which is worse than "in a limited scope".不同的人会有不同的想法,但“在头文件中的顶层”比“在 cpp 文件中的顶层”更糟糕,后者比“在有限范围内”更糟糕。 Some people never write using namespace std;有些人从不写using namespace std; at all.根本。

[*] That means C++ standard headers are permitted to put stuff in the global namespace but not required to. [*] 这意味着允许 C++ 标准标头将内容放入全局命名空间,但不是必需的。 So you have to avoid colliding with those symbols, but you can't actually use them because they might not be there.所以你必须避免与那些符号发生冲突,但实际上你不能使用它们,因为它们可能不存在。 Basically, the global namespace in C++ is a minefield, try to avoid it.基本上,C++ 中的全局命名空间是一个雷区,尽量避免它。 One might argue that the committee has ratified a practice by implementations that is nearly as harmful as sticking using namespace std;有人可能会争辩说,委员会已经通过实施批准了一种几乎与坚持using namespace std; at top level in a header file -- the difference being that the implementations only do it for symbols in the C standard library, whereas using namespace std;在头文件的顶层——不同之处在于实现只对 C 标准库中的符号执行此操作,而using namespace std; does it for C++-only symbols too.它也适用于 C++-only 符号。 There's a section in the C standard that lists names reserved for future additions to the standard. C 标准中有一节列出了为将来添加到标准中而保留的名称。 It's not a completely stupid idea to treat those names as reserved in the C++ global namespace too, but it's not essential.将这些名称也视为 C++ 全局名称空间中的保留名称并不是一个完全愚蠢的想法,但这不是必需的。

Including cstdint imports the symbol names in std namespace and possibly in Global namespace.包含cstdint会在 std 命名空间和可能在 Global 命名空间中导入符号名称。
Including stdint.h imports the symbol names in Global namespace and possibly in std namespace.包含stdint.h会在全局命名空间和可能的 std 命名空间中导入符号名称。

Features of C standard Library are also provided in the C++ Standard library and as a general naming convention they are pre-pended by an c to the corresponding names in C standard library. C 标准库的特性也在 C++ 标准库中提供,并且作为一般命名约定,它们在 C 标准库中的相应名称前加上一个 c。

In C++, You should be using:在 C++ 中,您应该使用:

#include <cstdint>

and fully qualify the symbol names you use with std::并完全限定您使用std::的符号名称
while in C, You should use:在 C 中,您应该使用:

#include <stdint.h>

Annex D (normative) Compatibility features [depr] states:附件 D(规范性)兼容性特征 [depr]指出:

D.6 C standard library headers D.6 C 标准库头文件

1 For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 151. 1 为了与 C 标准库和 C Unicode TR 兼容,C++ 标准库提供了 25 个 C 头文件,如表 151 所示。

Which include:其中包括:

<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> <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>

And further,并进一步,

2 Every C header, each of which has a name of the form name.h , behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. 2每个 C 头文件(每个头文件都具有name.h形式的名称)的行为就好像由相应的cname header放置在标准库名称空间中的每个名称都放置在全局名称空间范围内一样。 It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式使用声明 (7.3.3) 注入全局命名空间范围。

3 [ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. 3 [示例:标头<cstdlib>肯定会在命名空间 std 中提供其声明和定义。 It may also provide these names within the global namespace.它还可以在全局命名空间中提供这些名称。 The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard.头文件<stdlib.h>确实在全局命名空间中提供了相同的声明和定义,就像在 C 标准中一样。 It may also provide these names within the namespace std.它还可以在命名空间 std 中提供这些名称。 —end example ] ——结束例子]

  1. cstdint is C++11 header, stdint.h is C99 header (C and C++ are different languages!) cstdint是 C++11 头文件, stdint.h是 C99 头文件(C 和 C++ 是不同的语言!)

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

  3. Implementations of cstdint are mostly simply #include <stdint.h> with some namespace/language fixes. cstdint的实现主要是简单的#include <stdint.h>和一些命名空间/语言修复。

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

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