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

发布于 2024-10-19 20:43:02 字数 433 浏览 2 评论 0原文

在 GCC 4.4.3(适用于 Android)中使用 -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

与 C++0x 不兼容吗?

I'm having troubles with <stdint.h> when using -std=c++0x in GCC 4.4.3 (for Android):

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

But using -std=gnu++0x works:

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

Is <stdint.h> incompatible with C++0x?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦太阳 2024-10-26 20:43:02

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

原因如下,参考 n3225 来了解 -std=c++0x 的预期行为:

D.7 说

每个 C 标头,每个标头都有一个
name.h 形式的名称,其行为就像
标准中的每个名称
库名称空间由相应的
cname 标头位于
全局命名空间范围

好的,到目前为止很简单。 在标准库命名空间中放置什么?

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< /代码>。因此,需要 提供 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

So far as I can tell, I think this could be argued an implementation bug (or actually, since C++0x isn't published, not a bug per se but an incomplete implementation of the current state of the upcoming standard).

Here's why, referring to n3225 for the expected behavior of -std=c++0x:

D.7 says

Every C header, each of which has a
name of the form name.h, behaves as if
each name placed in the standard
library namespace by the corresponding
cname header is placed within the
global namespace scope

OK, so far so easy. What does <cstdint> place in the standard library namespace?

18.4.1:

typedef unsigned integer type uint64_t; // optional

How optional? 18.4.1/2:

The header defines all functions,
types, and macros the same as 7.18 in
the C standard

Drat. What does the C standard say? Taking out n1256, 7.18.1.1/3:

These types are optional. However,
if an implementation provides integer
types with widths of 8, 16, 32, or 64
bits, no padding bits, and (for the
signed types) that have a
two's complement representation, it
shall define the corresponding typedef
names

But hang on, surely on Android with -std=c++0x GCC does provide a 64 bit unsigned type with no padding bits: unsigned long long. So <cstdint> is required to provide std::uint64_t and hence stdint.h is required to provide uint64_t in the global namespace.

Go on, someone tell me why I'm wrong :-) One possibility is that C++0x refers to "ISO/IEC 9899:1999 Programming languages — C" without specifying a version. Can it really be that (a) 7.18.1.1/3 was added in one of the TCs, and also (b) C++0x intends to reference the original standard as of 1999, not the amendments since then? I doubt either of these is the case, but I don't have the original C99 on hand to check (a) and I'm not even sure how to check (b).

Edit: oh, as for which one should be used -std=c++0x isn't really a strict standards-compliant mode yet, since there isn't a strict standard yet. And even if there was a standard, gcc 4.4.3 certainly isn't a finished implementation of it. So I see no great need to use it if -std=gnu++0x is actually more complete, at least in this respect for your combination of gcc version and platform.

However, gnu++0x will enable other GNU extensions, that you might not want your code to use. If you're aiming to write portable C++0x, then eventually you'd want to switch to -std=c++0x. But I don't think GCC 4.4 or any other C++0x implementation-in-progress is complete enough yet for it to be practical to write code from the (draft) standard, such that you could say with a straight face "I'm programming C++0x, and it's only 2011!". So I'd say, use whichever one works, and understand that whichever one you use now, you'll probably be switching to -std=c++11 eventually anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文