14

我对 c++ 有点陌生,我已经完成了很多文件的编码任务,但我注意到 VS2012 似乎对以下语句有问题:

typedef std::uint32_t identifier;

但是,似乎将其更改为

typedef uint32_t identifier;

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

4

2 回答 2

16

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

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

早期版本的 Visual Studio 没有这个头文件,所以这肯定很麻烦。

由于所有这些疯狂,大多数人将求助于第三方实施,例如boost/cstdint.hpp.

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

于 2013-02-14T21:06:21.280 回答
14

uint32_t(也::uint32_t就是全局命名空间中的那个)在<stdint.h>. 该标头也可能在 namespace 中声明它std, as std::uint32_t,但这不是必需的。

std::uint32_t(即命名空间中的那个std)在<cstdint>. 该标头也可能在全局命名空间中声明它, as ::uint32_t,但不是必须这样做。

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

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

于 2013-02-14T21:19:09.710 回答