2013-02-14 98 views
8

我有点新的C++和我有很多已经完成文件的编码分配,但我注意到,VS2012似乎与下面的语句的问题:为什么std :: uint32_t与uint32_t不同?

typedef std::uint32_t identifier;

然而,似乎它更改为

typedef uint32_t identifier;

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

+0

这是VS 2010中的错误。我无法测试VS 2012,因为用户界面太不可用,无法安装。 – 2013-02-14 21:02:12

+4

我相信你需要包含'cstdint'来获得std命名空间的一个 – Caesar 2013-02-14 21:06:11

+1

@CodyGray OP似乎使用VS2012,所以UI不是不可用的。 – 2013-02-14 21:06:36

回答

10

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

它可能是你的编译器隐式定义了这种类型。无论如何,您应该包括cstdint以使名称空间std中的版本可用(可能还有全局名称空间中的版本)。包括stdint.h应该只提供不合格的版本。

早期版本的Visual Studio在没有此标头的情况下发货,所以这样做肯定会很麻烦。

由于所有这些疯狂,大多数人会回落在第三方实施,如boost/cstdint.hpp

编辑:他们是相同的,并为相同的目的。通常情况下:如果要使用std名称空间中的版本,请包括cstdint。如果您想要全局命名空间中的一个,请包括stdint.h。对于C++,建议使用std命名空间中的那个。作为一项规则:始终包括您使用的内容,不要依赖其他标题,包括适合自己的东西。

+0

但实质上,它们的功能是相同的? – Lunyx 2013-02-14 21:52:15

+0

@丹尼尔是的。我应该更强调这一点。所有关于编译器损坏的讨论可能比有帮助的更令人困惑。 – pmr 2013-02-15 01:08:53

7

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>,但不应该依赖该头文件,请为您使用的名称包含正确的头文件。