C99가 아닌 구조체 내의 익명 결합?
다음은 매우 간단한 문제 코드:
node_type 열거 {t_int, t_double}; 구조체 int_node {가치.}; 구조체 double_node {이중 값.}; 구조 노드 {열거 node_type 유형;유니온 { 구조체 int_node int_n; 구조체 double_node double_n; };}; int main(main){구조체 int_node i;i.value = 10;구조체 노드 n;n.type = t_int;n.int_n = i;반환 0;}
그리고 내가 언급하지 않은 것은 다음과 같다.
$cc us.c.$cc -std=c99 us.c.c.us.c:18:4: 경고: 선언은 어떤 것도 선언하지 않음us.c: 함수 'main'에서: us.c:26:4: 오류: 'int_n'이라는 이름의 멤버가 'int_n'에 없음
사용.GCC
-std
option은 위의 코드를 문제없이 컴파일하지만 (그리고 비슷한 코드는 꽤 잘 작동하고 있다)c99
이 기술을 허용하지 않는다.왜 그럴까, 만드는 것이 가능한가.c99
(또는)c89
c90
?)호환?고마워요.
나는 이 질문을 다른 사람들이 한 지 약 1년 반 후에 찾을 수 있다. 그래서 나는 다른 대답을 할 수 있다. 익명의 구조체들은 C99 표준에 있지 않지만 C11 표준에 있다.GCC와 clang은 이미 이를 지원하고 있다(C11 표준은 Microsoft에서 해당 기능을 해제한 것으로 보이며, GCC는 한동안 일부 MSFT 확장에 대한 지원을 제공했다).
익명 조합은 GNU 확장이지 C 언어의 어떤 표준 버전의 일부가 아니다.c99+GNU 확장에 -std=gnu99 같은 것을 사용할 수 있지만, 통사당만 제공하는 확장에 의존하지 말고 적절한 C를 쓰는 것이 가장 좋다...
편집: C11에 익명의 조합이 추가되어 현재 언어의 표준 부분이 되었다.추정컨대 GCC는-std=c11
네가 그것들을 사용할 수 있게 해줘.
익명성에 대한 해명만을 위해서.struct
또는 익명으로union
.
6.7.2.1 구조 및 조합 지정자
유형 지정자가 태그가 없는 구조 지정자인 익명 구성원을 익명 구조라고 하고, 유형 지정자가 태그가 없는 조합 지정자를 익명 조합원이라고 한다.익명구조나 조합의 조합원은 그 포함하는 구조나 조합의 조합원으로 간주된다.이는 포함된 구조나 조합이 익명인 경우에도 반복적으로 적용된다.
C99 익명의 구조체나 조합은 없다.
단순화:Type-specifierIdentifier {
선언리스트 }
태그 ;
- 형식 지정자:
struct
또는union
; - 식별자: 선택 사항, 에 대한 사용자 정의 이름
struct
또는union
; - 선언 목록: 구성원, 변수, 익명
struct
그리고 익명의union
- 태그: 선택 사항.만약 당신이 a를
typedef
형식 지정자 앞에서 태그는 태그가 아니라 별칭이다.
의 것이다.struct
또는 익명으로union
식별자와 태그가 없고 다른 내부에 존재하는 경우에만struct
또는union
.
struct s {
struct { int x; }; // Anonymous struct, no identifier and no tag
struct a { int x; }; // NOT Anonymous struct, has an identifier 'a'
struct { int x; } b; // NOT Anonymous struct, has a tag 'b'
struct c { int x; } C; // NOT Anonymous struct
};
struct s {
union { int x; }; // Anonymous union, no identifier and no tag
union a { int x; }; // NOT Anonymous union, has an identifier 'a'
union { int x; } b; // NOT Anonymous union, has a tag 'b'
union c { int x; } C; // NOT Anonymous union
};
typedef
hell: 만약 당신이 a를 가지고 있다면typedef
태그 부분은 더 이상 태그가 아니라 해당 유형의 별칭이다.
struct a { int x; } A; // 'A' is a tag
union a { int x; } A; // 'A' is a tag
// But if you use this way
typedef struct b { int x; } B; // 'B' is NOT a tag. It is an alias to struct 'b'
typedef union b { int x; } B; // 'B' is NOT a tag. It is an alias to union 'b'
// Usage
A.x = 10; // A tag you can use without having to declare a new variable
B.x = 10; // Does not work
B bb; // Because 'B' is an alias, you have to declare a new variable
bb.x = 10;
아래 예제는 그냥 바뀐다.struct
을 위해union
, 같은 방법으로 일한다.
struct a { int x; }; // Regular complete struct type
typedef struct a aa; // Alias 'aa' for the struct 'a'
struct { int x; } b; // Tag 'b'
typedef struct b bb; // Compile, but unusable.
struct c { int x; } C; // identifier or struct name 'c' and tag 'C'
typedef struct { int x; } d; // Alias 'd'
typedef struct e { int x; } ee; // struct 'e' and alias 'ee'
해결책은 연합의 인스턴스(익명성이 없는 데이터 유형으로 유지될 수 있음)를 명명하고 그 이름을 대리인으로 사용하는 것이었습니다.
$ diff -u old_us.c us.c.c.---- old_us.c 2010-07-12 13:49:25.0000000 +0200+us.c 2010-07-12 13:49:02.0000000 +0200@@ -15,7 +15,7 @@유니온 {구조체 int_node int_n;구조체 double_node double_n;- };+ } 데이터;}; int main(main){@@ -23,6 +23,6 @@i.value = 10;구조체 노드 n;n.type = t_int;- n.int_n = i;+ n.data.int_n = i;반환 0;}
이제 그것은 다음과 같이 편찬된다.c99
문제없이
$cc -std=c99 us.c.c.$
주: 어쨌든 나는 이 해결책에 만족하지 않는다.
C99의 6.2.7.1을 보면 식별자는 선택 사항임을 알 수 있다.
struct-or-union-specifier:
struct-or-union identifier-opt { struct-declaration-list }
struct-or-union identifier
struct-or-union:
struct
union
struct-declaration-list:
struct-declaration
struct-declaration-list struct-declaration
struct-declaration:
specifier-qualifier-list struct-declarator-list ;
specifier-qualifier-list:
type-specifier specifier-qualifier-list-opt
type-qualifier specifier-qualifier-list-opt
나는 여기저기 찾아다녔는데, 익명의 조합이 그 사양에 반대한다는 어떤 언급도 찾을 수가 없다.는 이 이 이-사라는 것을 identifier
6.1에 따른 선택 사항.
유니온에는 이름이 있어야 하며 다음과 같이 선언되어야 한다.
union UPair {
struct int_node int_n;
struct double_node double_n;
};
UPair X;
X.int_n.value = 12;
또 다른 해결책은 공통 헤더 값을 넣는 것이다.enum node_type type
모든 구조로, 그리고 당신의 최고 수준의 구조를 연합으로 만든다.꼭 '너 자신을 반복하지 말라'는 말은 아니지만, 익명의 조합과 불편해 보이는 대리 가치관을 모두 피한다.
enum node_type {
t_int, t_double
};
struct int_node {
enum node_type type;
int value;
};
struct double_node {
enum node_type type;
double value;
};
union node {
enum node_type type;
struct int_node int_n;
struct double_node double_n;
};
int main(void) {
union node n;
n.type = t_int; // or n.int_n.type = t_int;
n.int_n.value = 10;
return 0;
}
참조URL: https://stackoverflow.com/questions/3228104/anonymous-union-within-struct-not-in-c99
'programing' 카테고리의 다른 글
구성 요소를 게으르게 로드할 때 얕은 마운트가 마운트처럼 작동함 (0) | 2022.04.29 |
---|---|
스프링 응용 프로그램 컨텍스트 가져오기 (0) | 2022.04.29 |
기호 테이블이란? (0) | 2022.04.29 |
VueX 저장소 테스트 (0) | 2022.04.29 |
v-if 및 v-properties inside(다른 텍스트 렌더링용) (0) | 2022.04.29 |