代码之家  ›  专栏  ›  技术社区  ›  Adrian McCarthy

为什么C++不允许匿名结构?

  •  78
  • Adrian McCarthy  · 技术社区  · 16 年前

    一些C++编译器允许匿名联盟和结构作为标准C++的扩展。这是一点句法上的甜头,偶尔非常有用。

    阻止这项工作成为标准一部分的理由是什么?是否存在技术障碍?哲学上的?或者仅仅是没有足够的理由来证明这一点?

    以下是我所说的示例:

    struct vector3 {
      union {
        struct {
          float x;
          float y;
          float z;
        };
        float v[3];
      };
    };
    

    我的编译器将接受这个,但它警告说 "nameless struct/union" is a non-standard extension to C++ .

    6 回复  |  直到 8 年前
        1
  •  38
  •   bames53    13 年前

    正如其他人指出的,在标准C++中允许匿名联盟,但匿名结构不允许。

    这样做的原因是C支持匿名联合但不支持匿名结构*,所以C++支持前者兼容但不支持后者,因为它不需要兼容性。

    此外,C++中的匿名结构也没有多大用处。您演示的用法是,拥有一个包含三个浮点的结构,可以通过 .v[i] .x ,请 .y .z 我相信C++中没有定义的行为。C++不允许你给工会的一个成员写信,比如说 .v[1] ,然后从另一个成员那里读,比如 Y . 虽然这样做的代码并不少见,但实际上并没有很好的定义。

    C++为用户定义的类型提供了可选的解决方案。例如:

    struct vector3 {
      float v[3];
      float &operator[] (int i) { return v[i]; }
      float &x() { return v[0]; }
      float &y() { return v[1]; }
      float &z() { return v[2]; }
    };
    

    *C11显然添加了匿名结构,因此对C++的未来修订可能会添加它们。

        2
  •  17
  •   bobobobo    13 年前

    我会说,你可以清理你的 vector3 声明只使用 union

    union vector3 {
      struct { float x, y, z; } ;
      float v[3] ;
    } ;
    

    当然, anonymous structures was an MSVC extension . 但是ISO C11现在允许了,并且 gcc allows it 苹果的LLVM编译器也是如此。

    为什么在C11而不是C++ 11?我不确定,但实际上大多数(Gcc++,MSVC++和苹果C++编译器)C++编译器支持它们。

        3
  •  7
  •   Dan    16 年前

    不知道你的意思。C++规范的第9.5条,第2条:

    形式的结合

    union { member-specification } ;
    

    称为匿名联合;它定义未命名类型的未命名对象。

    你也可以这样做:

    void foo()
    {
      typedef
      struct { // unnamed, is that what you mean by anonymous?
        int a;
        char b;
      } MyStructType; // this is more of a "C" style, but valid C++ nonetheless
    
      struct { // an anonymous struct, not even typedef'd
        double x;
        double y;
      } point = { 1.0, 3.4 };
    }
    

    不总是很有用…尽管有时在讨厌的宏定义中有用。

        4
  •  1
  •   David Thornley    16 年前

    工会可以匿名;见标准9.5第2段。

    您认为匿名结构或类实现的目的是什么?在猜测为什么标准中没有某个东西之前,我想知道为什么它应该是,并且我看不到匿名结构的用途。

        5
  •  1
  •   JonM    16 年前

    根据编辑、评论和此msdn文章: Anonymous Structures 我敢猜测——它与封装的概念不太吻合。除了添加一个成员外,我不希望类的成员会干扰我的类命名空间。此外,对匿名结构的更改可能会在未经许可的情况下影响我的类。

        6
  •  1
  •   kennytm    13 年前

    你的代码

    union {
      struct {
        float x;
        float y;
        float z;
      };
      float v[3];
    };
    

    就像

    union Foo {
       int;
       float v[3];
    };
    

    这肯定是无效的(在C99和之前)。

    原因是 可能 为了简化解析(在C中),因为在这种情况下,您只需要检查结构/联合体是否只有类似于

    Type field;
    

    这就是说, gcc and "other compilers" 支持未命名字段作为扩展名。

    编辑: 匿名结构现在在C11中得到了官方支持(_§6.7.2.1/13)。