GCC在-std = gnu ++ 0x和-std = c ++ 0x之间有什么区别?应该使用哪一个?

时间:2011-02-27 20:30:30

标签: android c++ gcc c++11 compiler-options

在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不兼容吗?

1 个答案:

答案 0 :(得分:20)

据我所知,我认为这可能是一个实现错误(实际上,因为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:

  

标题定义了所有功能,   类型和宏与7.18相同   C标准

讨厌鬼。 C标准说什么?取出n1256,7.18.1.1/3:

  

这些类型是可选的。然而,   如果实现提供整数   宽度为8,16,32或64的类型   位,没有填充位,和(对于   签名类型)有一个   它的两个补码表示   应定义相应的typedef   名称

但请坚持,肯定在Android上使用-std=c++0x GCC 提供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