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

Lun*_*nyx 12 c++ visual-studio-2012

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

typedef std::uint32_t identifier;

但是,似乎将其改为

typedef uint32_t identifier;

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

pmr*_*pmr 14

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

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

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

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

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


Jon*_*ely 11

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>但你不应该依赖它,包括你使用的名称的正确标题.

  • `::uint32_t` 和 `std::uint32_t` 保证相同吗?或者,在混合这两种类型时,特别是当模板发挥作用时,我会遇到麻烦吗? (2认同)
  • 保证它们是同一类型的typedef。 (2认同)
  • @AndreySemashev,错误,请参见 [\[depr.c.headers\] p3](https://timsong-cpp.github.io/cppwp/n4659/depr.c.headers#3) -- `&lt;name.正如我所说,h&gt;` 标头可以将名称添加到 `std` 以及全局命名空间。[\[实例\]](https://godbolt.org/z/G_SKuV) (2认同)