27

在 GCC 4.4.3(适用于 Android)中<stdint.h>使用时遇到问题:-std=c++0x

// using -std=c++0x
#include <stdint.h>
uint64_t value;  // error: 'uint64_t' does not name a type

但使用-std=gnu++0x作品:

// using -std=gnu++0x
#include <stdint.h>
uint64_t value;  // OK

<stdint.h>与 C++0x 不兼容?

4

1 回答 1

21

据我所知,我认为这可能是一个实现错误(或者实际上,由于 C++0x 没有发布,本身不是一个错误,而是对即将发布的标准的当前状态的不完整实现)。

这就是为什么,指的是 n3225 的预期行为-std=c++0x

D.7 说

每个 C 标头(每个都有一个名为 name.h 的名称)的行为就好像每个由相应 cname 标头放置在标准库命名空间中的名称都放置在全局命名空间范围内

好的,到目前为止很容易。<cstdint>标准库命名空间中有什么?

18.4.1:

typedef unsigned integer type uint64_t; // optional

可选性如何?18.4.1/2:

标头定义了与 C 标准中的 7.18 相同的所有函数、类型和宏

德拉特。C标准是怎么说的?取出n1256、7.18.1.1/3:

这些类型是可选的。但是,如果实现提供了宽度为 8、16、32 或 64 位的整数类型,没有填充位,并且(对于有符号类型)具有二进制补码表示,则它应定义相应的 typedef 名称

-std=c++0x但是请稍等,在带有GCC的 Android 上确实提供了一个没有填充位的 64 位无符号类型:unsigned long long. 因此<cstdint>需要提供std::uint64_t,因此stdint.h需要uint64_t在全局命名空间中提供。

继续,有人告诉我为什么我错了 :-) 一种可能性是 C++0x 指的是“ISO/IEC 9899:1999 编程语言 - C”而没有指定版本。真的是 (a) 7.18.1.1/3 被添加到其中一个 TC 中,而且 (b) C++0x 打算参考 1999 年的原始标准,而不是此后的修订吗?我怀疑其中任何一种情况,但我手头没有原始的 C99 来检查 (a),我什至不知道如何检查 (b)。

编辑:哦,至于应该使用哪个-std=c++0x还不是严格的标准兼容模式,因为还没有严格的标准。即使有标准,gcc 4.4.3 也肯定不是它的完整实现。-std=gnu++0x因此,如果实际上更完整,我认为没有太大必要使用它,至少在这方面对于您的 gcc 版本和平台的组合而言。

但是,gnu++0x将启用您可能不希望您的代码使用的其他 GNU 扩展。如果您的目标是编写可移植的 C++0x,那么最终您会想要切换到-std=c++0x. 但我认为 GCC 4.4 或任何其他正在进行的 C++0x 实现还不够完整,以至于从(草案)标准编写代码是实用的,这样你就可以直截了当地说“我'我正在编程 C++0x,而这只是 2011 年!”。所以我想说,使用任何一个有效的,并理解你现在使用的任何一个,你-std=c++11最终可能会切换到。

于 2011-02-27T22:35:53.743 回答