C ++에서 익명 구조체를 허용하지 않는 이유는 무엇입니까? 제가 말하는 내용의 샘플입니다. struct vector3

일부 C ++ 컴파일러는 표준 C ++에 대한 확장으로 익명 공용체 및 구조체를 허용합니다. 때때로 매우 도움이되는 약간의 통 사적 설탕입니다.

이것이 표준의 일부가되는 것을 막는 근거는 무엇입니까? 기술적 인 장애물이 있습니까? 철학적입니까? 아니면 정당화 할 필요가 충분하지 않습니까?

다음은 제가 말하는 내용의 샘플입니다.

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

내 컴파일러는 이것을 받아들이지 만 “nameless struct / union”이 C ++에 대한 비표준 확장 이라고 경고합니다 .



답변

다른 사람들이 지적했듯이 익명 공용체는 표준 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 ++ 개정판에서 추가 할 수 있습니다.


답변

나는 vector3단지 사용 하여 선언을 정리할 수 있습니다 .union

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

물론 익명 구조 MSVC 확장 이었습니다. 그러나 ISO C11은 지금 그것을 허용하고 gcc는 그것을 허용하며 Apple의 llvm 컴파일러도 허용합니다.

왜 C ++ 11이 아닌 C11입니까? 확실하지는 않지만 실제로 대부분 (gcc ++, MSVC ++ 및 Apple의 C ++ 컴파일러) C ++ 컴파일러가이를 지원합니다.


답변

당신이 무슨 뜻인지 확실하지. 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 };
}

항상별로 유용하지는 않지만 … 때로는 불쾌한 매크로 정의에 유용합니다.


답변

공용체는 익명 일 수 있습니다. 표준, 9.5 단락 2를 참조하십시오.

익명의 구조체 또는 클래스가 어떤 목적을 충족한다고 생각합니까? 표준에없는 이유를 추측하기 전에 그 이유를 알고 싶습니다. 익명 구조체에 대한 용도는 보이지 않습니다.


답변

편집, 주석 및이 MSDN 문서 : Anonymous Structures를 기반으로 추측 할 수 있습니다. 캡슐화 개념에 맞지 않습니다. 클래스의 멤버가 단순히 멤버를 하나만 추가하는 것 이상으로 클래스 네임 스페이스를 엉망으로 만들기를 기대하지는 않습니다. 또한 익명 구조를 변경하면 허가없이 수업에 영향을 미칠 수 있습니다.


답변

귀하의 코드

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

처럼

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

확실히 유효하지 않습니다 (C99 이전).

그 이유는 아마도 구문 분석을 단순화하기위한 것입니다 (C에서).이 경우 구조체 / 유니온 본문에 다음과 같은 “선언자 문”만 있는지 확인하기 만하면됩니다.

Type field;

즉, gcc 및 “다른 컴파일러” 는 이름없는 필드를 확장으로 지원합니다.

편집 : 이제 익명 구조체가 C11 (§6.7.2.1 / 13)에서 공식적으로 지원됩니다.