programing

C 빈 구조체 - 이것은 무엇을 의미하나?

prostudy 2022. 5. 13. 23:49
반응형

C 빈 구조체 - 이것은 무엇을 의미하나?

나는 이 코드를 내가 사용해야 하는 장치의 헤더 파일에서 찾았고, 비록 몇 년 동안 C를 해왔지만, 나는 결코 이런 일에 부딪힌 적이 없다.

struct device {
};

struct spi_device {
    struct device dev;
};

다음에서와 같이 사용됨:

int spi_write_then_read(struct spi_device *spi, 
const unsigned char *txbuf, unsigned n_tx,
unsigned char *rxbuf, unsigned n_rx);

다음 항목도 참조하십시오.

struct spi_device *spi = phy->spi;

동일한 것으로 정의되는 경우.

나는 이 정의의 요점이 무엇인지 잘 모르겠다.그것은 보드의 Linux 어플리케이션용 헤더 파일에 있지만, 그것이 사용하는 것에 당황한다.어떤 설명이나 아이디어라도?이전에 이것을 본 사람은 누구라도 (여러분 중 일부는 분명히 :를 가지고 있을 것이다.

고마워!:bp:

C 구조물은 적어도 하나의 명명된 구성원을 포함해야 하므로 C가 아니다.

(C11, 6.7.2.1 구조 및 조합 지정자 p8) "구조 신고 목록에 직접 또는 익명 구조 또는 익명 조합을 통해 명명된 조합원이 포함되지 않은 경우, 그 행동은 정의되지 않는다."

GNU C 확장자:

GCC는 C 구조물에 다음과 같은 구성원이 없는 것을 허용한다.

struct empty {
};

구조물의 크기는 0이다.

https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html

나는 너의 예에서 이 구조의 목적이 무엇인지 모르지만 일반적으로 나는 구조 유형의 전진 선언으로 사용될 수 있다고 생각한다. C++에서는 멤버가 없는 클래스가 허용된다는 점에 유의하십시오.

에서는 Linux 2.4의 빈 구조 .spin_lock_tLinux 커널 2.4(포함/리눅스/spinlock 포함)에 별칭을 입력하십시오.h:

#if (DEBUG_SPINLOCKS < 1)

/* ... */

typedef struct { } spinlock_t;

#elif (DEBUG_SPINLOCKS < 2)

/* ... */

typedef struct {
    volatile unsigned long lock;
} spinlock_t;

#else /* (DEBUG_SPINLOCKS >= 2) */

/* ... */

typedef struct {
    volatile unsigned long lock;
    volatile unsigned int babble;
    const char *module;
} spinlock_t;

#endif

만약의 경우에 대비하여 기능 API를 변경할 필요 없이 공간을 절약하는 것이 목적이다.DEBUG_SPINLOCKS < 1. 또한 타입의 더미(제로사이즈) 객체를 정의할 수 있다.spinlock_t.

조건부 컴파일과 함께 사용되는 빈 구조 해킹의 (최근) 리눅스 커널의 또 다른 예로는/리눅스/장치를 포함한다.h:

struct acpi_dev_node {
#ifdef CONFIG_ACPI
    void *handle;
#endif
};

이 마지막 예는 Greg Kroah-Hartman과의 토론을 참조하십시오.

https://lkml.org/lkml/2012/11/19/453

이것은 표준 C가 아니다.
C11: 6.2.5-20:

— 구조 유형은 순차적으로 할당된 비빈 멤버 개체 집합(그리고 특정 상황에서 불완전한 배열)을 설명하며, 각 개체에는 선택적으로 지정된 이름과 구별되는 유형이 있다.

J.2 정의되지 않은 동작:

그 행동은 다음과 같은 상황에서 정의되지 않는다.
....
지명된 구성원(익명 구조와 조합을 통해 간접적으로 지정된 구성원 포함)이 없는 구조 또는 조합(6.7.2.1)을 정의한다.

GCC는 이를 확장자로 사용한다(사용 시기와 장소에 대해서는 더 이상 자세히 설명되지 않음).어떤 프로그램에서든 이것을 사용하면 그것을 컴파일러로 구체화할 것이다.

도서관을 위해 이것을 해야 하는 한 가지 이유는 도서관 개발자들이 당신이 이러한 구조물의 내부를 알거나 간섭하는 것을 원하지 않기 때문이다.이 경우 구조물의 "인터페이스" 버전을 제공할 수 있다.spi_device/device(그것은 당신이 볼 수 있는 것이다) 그리고 실제 구성원과 함께 도서관 내부에서 사용하기 위해 언급된 구조물의 다른 버전을 정의하는 두 번째 유형 정의를 가지고 있다.

구조체 구성원에 접근할 수도 없고 심지어 그러한 유형의 호환 구조체를 만들 수도 없기 때문에(자신의 컴파일러도 이 구조체의 실제 크기를 알 수 없기 때문에), 이것은 도서관 자체에서 구조체를 만들 때에만 작동하며, 오직 당신에게 그 구조물에 대한 포인터를 전달하고, 당신이 어떤 구성원도 수정할 필요가 없다.

빈 구조체를 다른 구조체의 첫 번째 구성원으로 추가하면, 빈 구조체는 "마커 인터페이스" 역할을 할 수 있다. 즉, 내부 구조체의 포인터로 외부 구조체에 포인터를 던지고 깁스가 성공하면 외부 구조체가 "마커 인터페이스"로 표시된다는 것을 알 수 있다.

또한 그것은 확실하지는 않지만 미래의 발전을 위한 장소 보유자일 수도 있다.이게 도움이 되길 바래.

이것은 유효한 C이다.

struct empty;
struct empty *empty;

그리고 메모리 영역의 불투명한 주소의 사용을 용이하게 한다.

그러한 주소들은 보통 도서관 서브루틴에서 얻어서 도서관 서브루틴으로 전달된다.

예를 들어, 이런 일은 stdio.h에서 행해진다.

참조URL: https://stackoverflow.com/questions/24685399/c-empty-struct-what-does-this-mean-do

반응형