为什么std :: uint32_t与uint32_t不同?

时间:2013-02-14 20:55:56

标签: c++ visual-studio-2012

我对c ++有点新意,我已经完成了很多文件的编码工作,但我注意到VS2012似乎有以下声明的问题:

typedef std::uint32_t identifier;

然而,似乎将其更改为

typedef uint32_t identifier;

摆脱了错误。没有包含,这是在头文件中。我注意到定义是在stdint.h中。如果是这种情况,为什么这个代码在VS之外是可以接受的(即使用g ++正确编译)但在VS中是不可接受的?有人可以解释一下吗?

2 个答案:

答案 0 :(得分:13)

不同之处在于,一个位于命名空间内,另一个不位于命名空间内。否则他们应该是一样的。第一个应该是C版本,第二个是C ++版本。在C ++ 11之前,强制要求包含前缀版本而不是C标准库版本会在标准命名空间内引入所有C定义。在C ++ 11中,这种限制已经放宽,因为这并不总是可行。

可能是您的编译器隐式定义了此类型。在任何情况下,都应该包含cstdint以使命名空间std中的版本可用(并且可能是全局命名空间中的版本)。包括stdint.h应该只提供不合格的版本。

早期版本的Visual Studio没有这个标题,所以这一定很麻烦。

由于所有这些疯狂,大多数人都会依赖第三方实施,例如boost/cstdint.hpp

编辑:它们是相同的,并且用于相同的目的。通常:如果要使用std命名空间中的版本,请包含cstdint。如果您想要全局命名空间中的那个,请包含stdint.h。对于C ++,建议使用std命名空间中的那个。通常:始终包括您使用的内容,不要依赖其他标题,包括适合您的内容。

答案 1 :(得分:9)

uint32_t(又名::uint32_t,即全局命名空间中的那个)在<stdint.h>中声明。那个标题可能也在名称空间std中将其声明为std::uint32_t,但不需要这样做。

std::uint32_t(即名称空间std中的一个)在<cstdint>中声明。该标头可能也在全局命名空间中将其声明为::uint32_t,但不需要这样做。

  

如果是这种情况,为什么这个代码在VS之外是可以接受的(即使用g ++正确编译)但在VS中是不可接受的?有人可以解释一下吗?

如果您想使用std::uint32_t,则必须#include <cstdint>,否则代码可能无法编译。如果它使用G ++进行编译,那么可能其他一些标题间接包含<cstdint>,但您不应该依赖它,包括您使用的名称的正确标题。