在C ++中正确使用/包含uint64_t

时间:2017-06-21 06:04:25

标签: c++ c++11

供参考,我在C ++ 11中编译。

我开始使用电路板的位图表示作为以片段为中心的方法来编写国际象棋引擎。看起来合适的类型是uint64_t,但是,在网上搜索了一下之后,我对这里的“最佳实践”有点不确定。

我开始为游戏板定义.hpp文件。 首先,我对不同代码似乎表现出的类似行为感到困惑。

#include <cstdint>
uint64_t board;

#include <cstdint>
std::uint64_t board;

编译都很好。两者有什么区别?这个比那个好吗?

此外,我注意到我甚至不需要包含cstdint就可以使用uint64_t:

#include <iostream>
uint64_t board;

#include <iostream>
uint64_t std::board;

两者都编译得很好,就像上面的2个cstdint示例一样。因此,我对如何在C ++ 11中使用uint64_t感到困惑,以及为什么所有这四个例子都完全相同。我被告知你想使用cstdint,但似乎iostream也提供了def类型?是否存在“最佳/最安全”的特定方式(例如,在名称空间冲突方面)?

1 个答案:

答案 0 :(得分:23)

{C}中存在<cthing>标头作为其C传承的一部分。标准库不是重新发明轮子,而是重用C标准库的这些有用部分。现在,不同之处在于标题已重命名,并且必须在名称空间std中定义其符号。他们还可以将它们添加到全局命名空间。请注意,他们可能这样做,而不是必须

这是因为这些标头(作为实现细节)将包含纯C标头<thing.h>,并根据全局标头定义std::符号。但这不是你可以依赖的东西。标准库实现者可能有一天会决定他们将不再这样做。如果您添加cstdint并使用uint64_t代替std::uint64_t,您的计划可能会随机停止成功构建。

唯一的保证是,std命名空间中的符号将存在。因此,您应该使用这些符号而不是全局符号。

现在,作为其自身实现的一部分,标准库可以在其自身内交叉包含自己的头。您的版本很可能包含<cstdint>,以便实施<iostream>。但同样,这是一个实现细节,而不是C ++标准的硬性要求。如果您的标准库版本发生更改,而不再更改,则代码将无法构建。

总之,要使代码在不同的编译器和标准库实现中尽可能可移植:

  1. 包含<cstdint>并使用它在命名空间std中定义的符号,这些符号必须存在。 1
  2. 如果您需要任何符号,请在文档中包含保证存在的标题。不要依赖偶然发现的实施细节。
  3. (1)从技术上讲,允许未定义固定宽度的整数类型。这是因为标准意识到并非所有平台都能定义所有平台。实际上,您可以在现代台式机上使用它们。