2011-08-03 3 views
1

저는 C1x의 익명 구조에 대해 다소 혼란 스럽습니다. 적절하게 변환 된 구조체 포인터가 첫 번째 멤버를 가리키는 규칙이 초기 익명 구조체에 적용되는지 또는 단순히 초기 익명 구조체의 초기 멤버에 적용되는지 규칙이 적용됩니까? 특히이 프로그램은 C1x에서 의미가 있습니까?구조 포인터가 C1x의 초기 익명 멤버를 가리 키도록 변환 할 수 있습니까? 이것도 올바른 질문입니까?

#include<stdio.h> 

struct node { 
    struct node *next; 
}; 

/* Does C1x even allow this? Do I have to define struct node inside of inode? 
* Are anonymous struct members even allowed to have tags? 
*/ 
struct inode { 
    struct node; 
    int data; 
}; 

int main(void) { 
    inode node1 = {NULL, 12}; 
    inode *ihead = &inode; 
    node *head = (struct node *)ihead; 

    /* These should work since struct inode's first member is a struct node. */ 
    printf("Are these equal? %c", head == &node1.next ? 'Y' : 'N'); 
    printf("Is next NULL? %c", head->next == NULL ? 'Y' : 'N'); 

    return 0; 
} 

This 대답은 내가 대신 익명 구조체의 이름이 구조체에 대해 물어 될 수 있음을 시사한다. 익명 구조체의 본질을 완전히 오해하고 있습니까?

+0

나는 내 전화를 다시 때 대답을 보려고합니다. 그동안 나는 현상금을 더했습니다.나는이 행동을 용서해서는 안되지만이 질문에 부딪 치거나 그것에주의를 끌기위한 어떤 방법을 찾을 수 있는지보십시오. 나는 그 대답을 알고 싶다. –

답변

3
/* Does C1x even allow this? Do I have to define struct node inside of inode? 
* Are anonymous struct members even allowed to have tags? 
*/ 
struct inode { 
    struct node; 
    int data; 
}; 

첫째, struct node 회원은 익명 없습니다. 의 이름은이지만 태그 (node)가 있으므로 "익명"의 C1x 정의를 만족하지 않습니다.

그렇다면 C1x 문법은 분명히 허용됩니다. SO가 실제로 첨자를 지원하지 않기 때문에 대괄호로 선택적 요소를 표시했습니다. 또한이 유효 함을 볼 필요하지 않은 문법 규칙을 생략했습니다

type-specifier: 
    struct-or-union-specifier 
struct-or-union-specifier: 
    struct-or-union [identifier] { struct-declaration-list } 
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] 

이 만족해야 4 개 제약도 있지만, 그들 중 누구도 익명의 회원들에게 적용되지 않는다, 그래서 이것은 문법적으로 유효 C.

이제 진짜 질문에 답하십시오. C1x의 말 :

적절하게 변환 된 구조체 개체에 대한 포인터는 초기 멤버 (...)를 가리키고 그 반대의 경우도 마찬가지입니다.

풀 스톱. "해당 회원의 이름이 지정되지 않은 경우"는 없습니다. 따라서 node1에 대한 포인터는 이름이없는 초기 멤버에 대한 포인터이기도하며 node1.next에 대한 포인터이기도합니다. 그러나, 여기에 조금 털이 빠지기 시작합니다. 제가 단순히 절을 간과 한 것일 수도 있지만, C1x는 다음과 같이 말합니다 :

익명 구조체 또는 공용체의 멤버는 포함하는 구조체 또는 공용체의 멤버로 간주됩니다.

나는 이름이 구조의 구성원을 포함하는 구조의 구성원으로 간주됩니다 말하는 언어를 찾을 수 없습니다. 실제로 포인터 - 펀닝 이외의 next에 액세스하는 보장 된 방법이 없을 수도 있습니다. 나는위원회의 일부 사람들에게이 점에 대해 명확히하기를 요청할 것이다.

또한 초기화에 문제로 실행할 수 있습니다 : 구조 개체의

이름 회원도 초기화 후 불확정 값을 가지고있다.

+2

+1 표준위원회 작성만을위한 기금 (11 시간 이내에, 더 나은 것이 나오지 않는 한)을드립니다. 하지만 다시 쓸 때 업데이트하십시오. 이 (엄청나게 편리한) 구조가 기능이거나 "확장"으로 남아있게하려면 대단히 궁금합니다. –

+0

감사합니다, 죄송합니다. 답변을 수락하는 데 너무 오래 걸렸습니다. –

+0

그럼,위원회가 이것에 대한 판결을 했습니까? –

-1

노드를 유형 이름으로 사용해보십시오. "struct node"를 다시 선언하지 마십시오.

struct inode { 
    node n;//node is a already a defined type name, n is the var name 
    int data; 
}; 
+1

나는 이것이 늦었다는 것을 알고 있지만 이것이 C 질문이 아니고 C++ 질문이 아니기 때문에 downvoted라고 믿는다. 노드가 C에서 유형 이름이 되려면 typedef되어야합니다. –

+0

감사합니다 Michael, – robermorales