일부 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)에서 공식적으로 지원됩니다.