programing

순환 유형 종속성을 해결하시겠습니까?

topblog 2023. 8. 1. 20:15
반응형

순환 유형 종속성을 해결하시겠습니까?

이러한 구조물을 정의할 때 다음 순환 의존성을 해결하는 가장 좋은 방법은 무엇입니까?
C 언어 태그를 메모합니다. 표준 gcc C에서 해결책을 찾고 있습니다.

typedef struct {
    char* name;
    int age;
    int lefthanded;
    People* friends;
} Person;

typedef struct {
    int count;
    int max;
    Person* data;
} People;

답은 선언과 정의의 차이에 있습니다.같은 단계에서 선언하고 정의하려고 합니다(typeef를 통해 새 유형을 정의하는 경우).컴파일러가 당신이 말하는 것을 미리 알 수 있도록 당신은 이것들을 다른 단계로 나눌 필요가 있습니다.

typedef struct Person Person;
typedef struct People People;

struct Person {
    char* name;
    int age;
    int lefthanded;
    People* friends;
};

struct People {
    int count;
    int max;
    Person* data;
};

맨 위에 두 개의 '빈' 유형 정의가 추가됩니다(선언).이것은 컴파일러에게 새로운 유형의 사용자가 '사용자 구조' 유형임을 알려주어 사용자 구조의 정의 안에서 사용자 구조가 무엇을 의미하는지 알 수 있도록 합니다.

특정한 경우에는 사용자 유형 정의가 정의되기 전에 사용되는 유일한 유형이기 때문에 사용자 유형 정의를 사전에 선언하지 않아도 됩니다.[사용자] 구조 정의에 들어갈 때 이미 사용자 유형을 완전히 정의했습니다.따라서 다음과 같은 방법도 사용할 수 있지만 취약하기 때문에 권장되지 않습니다.

typedef struct People People;

typedef struct {
    char* name;
    int age;
    int lefthanded;
    People* friends;
} Person;

struct People {
    int count;
    int max;
    Person* data;
};

구조 정의 순서(사용자 유형 정의 위의 사용자 이동 구조)를 스왑하면 다시 실패합니다.그것이 이것을 취약하게 만드는 이유이며 따라서 권장되지 않습니다.

이 트릭은 포인터가 아닌 지정된 유형의 구조체를 포함하는 경우에는 작동하지 않습니다.예를 들어, 다음은 컴파일되지 않습니다.

typedef struct Bar Bar;

struct Foo
{
    Bar bar;
};

struct Bar
{
    int i;
};

위의 코드는 struct Foo의 정의 안에서 사용하려고 할 때 형식 Bar가 불완전하기 때문에 컴파일러 오류를 제공합니다.즉, 해당 시점에서 구조체 막대의 정의를 보지 못했기 때문에 구조체 부재 'bar'에 얼마나 많은 공간을 할당해야 하는지 알 수 없습니다.

코드는 다음을 컴파일합니다.

typedef struct Foo Foo;
typedef struct Bar Bar;
typedef struct FooBar FooBar;

struct Foo
{
    Bar *bar;
};

struct Bar
{
    Foo *foo;
};

struct FooBar
{
    Foo     foo;
    Bar     bar;
    FooBar  *foobar;
};

이것은 Foo와 Bar 내부의 원형 포인터에서도 작동합니다. 왜냐하면 'Foo'와 'Bar' 유형은 컴파일러가 이들에 대한 포인터를 만들 수 있도록 사전에 선언되었기 때문입니다.

FooBar를 정의할 때까지 Foo와 Bar의 크기를 정의하여 실제 개체를 포함할 수 있습니다.또한 FooBar 유형을 미리 선언했기 때문에 FooBar 유형에 대한 자체 참조 포인터를 포함할 수 있습니다.

struct FooBar의 정의를 struct Foo 또는 Bar의 정의 위로 이동한 경우 이전 예제(불완전한 유형)와 동일한 이유로 컴파일되지 않습니다.

다음 구조 중 하나를 정방향으로 선언합니다.


struct people;

typedef struct {
  /* same as before */
  struct people* friends;
} Person;

typedef struct people {
  /* same as before */
} People;

가독성에 관하여:

typedef struct Foo_ Foo;
typedef struct Bar_ Bar;

struct Foo_ {
    Bar *bar;
};

struct Bar_ {
    Foo *foo;
};

피해보는 것이 좋을 수도 있습니다.typedef struct전체적으로;

때부터Person에 대한 지침을 원할 뿐입니다.People후자를 미리 선언하는 것만으로도 괜찮을 것입니다.

typedef struct People People;

그런 다음 두 번째 선언을 다음과 같이 struct 태그를 사용하여 선언하도록 변경합니다.

struct People {
    int count;
    int max;
    Person data[];
};
struct _People;

typedef struct {
    char* name;
    int age;
    int lefthanded;
    struct _People* friends;
} Person;

struct _People {
    int count;
    int max;
    Person data[1];
};

참있: 음고Person data[];표준?

struct People_struct;

typedef struct {
    char* name;
    int age;
    int lefthanded;
    struct People_struct* friends;
} Person;

typedef struct People_struct {
    int count;
    int max;
    Person data[];
} People;

언급URL : https://stackoverflow.com/questions/888386/resolve-circular-typedef-dependency

반응형