为啥 C++11 不支持匿名结构,而 C11 支持?

Posted

技术标签:

【中文标题】为啥 C++11 不支持匿名结构,而 C11 支持?【英文标题】:Why does C++11 not support anonymous structs, while C11 does?为什么 C++11 不支持匿名结构,而 C11 支持? 【发布时间】:2012-01-27 04:35:49 【问题描述】:

C11 支持匿名结构,如下所示:

struct Foo

    struct
    
        size_t x, y;
    ;
;
struct Foo f;
f.x = 17;
f.y = 42;

基本上,此类struct 的成员被视为封闭structunion 的成员(递归,如果封闭结构本身是匿名的)。

C++11 不包括匿名结构的理由是什么?当然,它们只是非常有用(主要是在联合内部,以消除为struct 输入标识符)。但它们似乎是对规范的一个足够明显的补充(并且已经由许多编译器实现),肯定必须讨论它们,至少要保持与 C11 标准的兼容性。那么为什么不添加呢?

【问题讨论】:

我不同意这个问题没有建设性的投票。更温和的问题也可以。 实际上大多数 C++11 编译器也支持匿名结构。我在 MSVC++(从那时起)和 Apple 的 llvm C++11 编译器中都使用过它们。 MinGW 也支持匿名结构/联合。 【参考方案1】:

随着 C++ 和 C 语言的发展,我们几乎没有做出任何努力来保持 C++ 和 C 之间的兼容性。请注意,可变长度堆栈数组自 1999 年以来一直在 C 中,但未包含在 C++11 中。虽然他们通常不会引入相互矛盾的东西,但 C++ 委员会并没有完全向后弯曲以确保 C++11 与 C89 之后的 C 版本兼容。

此外,这个特性在 C++ 中会相当复杂,因为 struct 只不过是 class。匿名结构/类应该具有常规结构/类的所有功能,是吗?否则,拥有它有什么意义?

构造一个无名的struct 意味着什么?你会如何定义构造函数?一些简单的事情:

struct Foo

    struct
    
        size_t &x;
    ;
;

根本不可能,因为内部 struct 没有构造函数。而且没有办法指定一个。 struct 不能在其中构造另一个 struct 的成员。

对于这样的事情:

struct Foo

    size_t outer;
    struct
    
        void SomeFunc();
        size_t x;
    ;
;

this 指针 SomeFunc 得到什么? this 的类型是什么,无名和未命名的类型?您甚至如何在结构之外定义SomeFuncSomeFunc 的名称不能是 Foo::SomeFunc,因为 SomeFunc 位于内部范围内。

C++ 处理起来太复杂了。而且肯定不值得为增加这种复杂性而烦恼。

【讨论】:

这是有道理的,尽管我可以想象限制使其完全合理:POD,没有方法(继承或其他方式),并且完全公开,我认为可以解决您提出的问题。在我看来,匿名工会已经引入了许多这样的问题,所以这些问题对我来说似乎并不“太复杂”,除了解决这些问题的动力太少。 “构造一个无名结构意味着什么?你将如何定义构造函数?”。对于无名工会也可以要求同样的事情。联合也可以有构造函数。 此外,您在 C11 中从匿名结构中获得的大部分内容也可以从继承中获得。匿名联合会更有用,但正如 Nicol 指出的那样,整个功能不适合 C++。 "你将如何定义构造函数?"你不知道,内部匿名结构成员是封闭类的成员,它可能像任何其他成员一样初始化它们。 @Deduplicator:此外,匿名联合支持(即使在 C++98 中),尽管(可选)有构造函数。【参考方案2】:

扮演魔鬼的拥护者 - 类和结构声明通常用于包装特定于类的类型声明。

typedef struct 

 name;

因此应该是允许的。

因此

struct 

 

应该也是。

但是,如果我们认为这只是一个类的内部命名空间中的声明,就无法访​​问结构的内部。

由于 C 中的 struct != 命名空间,C 可以制定规则,例如通过周围的结构访问匿名结构。

为了让 C++ 允许这样做,它需要对这种情况进行特殊处理,这会使名称解析变得复杂。

当然,扮演魔鬼的魔鬼代言人 - C 实际上就是这样做的。它为名称解析增加了一个额外的级别 - 如果您在结构中找不到名称,请检查结构的匿名成员。这有点神奇,在某种程度上我可以看到 C++ 委员会成员觉得很烦。

这也引发了一些问题——如果一个匿名结构可以通过其父类访问,那么命名空间中的匿名结构呢?

当然,如果您真的想知道,只需询问 Stroustrup - 他会回复电子邮件。

【讨论】:

这不可能是正确的原因 --- 支持匿名联合 (即使在 C++98 中!),但匿名结构不支持?如果这是原因,那么也不应该支持匿名联合,因为它们与结构共享相同的命名空间。 我觉得“小魔法”有点有趣。在我看来更像是“这不是 C。我们决定。neener-neener。” C++ 已经支持内容溢出的匿名联合和匿名命名空间,就好像它们在外部范围内被声明为内联一样。匿名结构完成了这个三重奏(在图形编程中特别有用)。另一方面,C++11 甚至超越了 C 并支持内联命名空间(即使是命名的,而不仅仅是匿名的)。 ***.com/questions/11016220/…

以上是关于为啥 C++11 不支持匿名结构,而 C11 支持?的主要内容,如果未能解决你的问题,请参考以下文章

C11语法汇总(仅记录遇到的坑)

gcc/g++支持c11

为啥 C11 或 C++11 中没有 ASCII 或 UTF-8 字符文字?

C语言中的匿名结构体

C语言中的匿名结构体

为啥结构不支持继承?