불완전한 유형에 대한 역 참조 포인터
나는 이것에 대해 많은 질문을 보았지만 특정 코드 없이는 다르게 질문 할 것입니다. 유형이 불완전한 원인 을 쉽게 파악할 수 있는 방법이 있습니까? 제 경우에는 다른 사람의 코드를 사용하고 있으며 헤더가 정확하지 않다고 확신하지만 (컴퓨터가 인간의 눈보다 훨씬 빠르고 더 나은 작업을 수행하기 때문에) 컴파일러가 말할 수있는 방법이 있습니다. , " 34 행에 X 형 이 있다고 생각 하지만 실제로는 없습니다 ." 오류 자체는 할당 할 때만 표시되므로별로 도움이되지 않습니다.
다른 날 누군가가 실수로 다음과 같은 것을 지정하여 불완전한 유형을 사용하는 질문을 보았습니다.
struct a {
int q;
};
struct A *x;
x->q = 3;
컴파일러는 키워드 덕분에 완전히 정의되지 struct A
않았지만 그것이 구조체 라는 것을 알고있었습니다 .A
struct
그것은 C ++에 있었는데, 그러한 사용 struct
은 비정형 적입니다 (그리고 발을 뗄 수 있습니다). C에서 할 경우
typedef struct a {
...
} a;
그런 다음 a
typename으로 사용 하고 struct
나중에 생략 할 수 있습니다 . 이렇게하면 이름을 잘못 입력하거나 헤더를 잊어 버린 경우 컴파일러에서 불완전한 유형이 아닌 나중에 정의되지 않은 식별자 오류를 제공합니다.
또 다른 가능한 이유는 간접 참조입니다. 코드가 현재 c 파일에 포함되지 않은 구조체를 참조하면 컴파일러가 불평합니다.
a-> b-> c // b가 현재 c 파일에 포함되지 않은 경우 오류
무슨 뜻입니까? 할당 할 때만 오류가 나타납니다. 예를 들어 GCC에서 할당이 보이지 않는 경우 :
int main() {
struct blah *b = 0;
*b; // this is line 6
}
incompletetype.c:6: error: dereferencing pointer to incomplete type
.
오류 는 6 행에 있으며, 마치 완전한 유형 인 것처럼 불완전한 유형을 사용한 곳입니다. 그때까지는 괜찮 았어요.
실수는 유형을 정의하는 헤더를 포함해야한다는 것입니다. 그러나 컴파일러는 어떤 줄에 포함되어야하는지 추측 할 수 없습니다. 함수 외부의 어떤 줄도 괜찮을 것입니다. 또한 시스템의 모든 텍스트 파일을 트롤링하여이를 정의하는 헤더를 찾고이를 포함해야한다고 제안하지도 않습니다.
또는 (좋은 점, potatoswatter) 실제로 존재하지만 실제로 지정된 유형을 지정 하려고 할 b
때 정의 된 줄에 오류가 있습니다 . 대부분의 경우 변수의 정의를 찾는 것이 너무 어렵지 않아야합니다. IDE는 일반적으로 당신을 위해 그것을 할 수 있으며 컴파일러 경고는 귀찮게 할 수 없습니다. 하지만 사용중인 항목의 정의를 찾을 수 없다면 꽤 끔찍한 코드입니다.blah
b
문제가 무엇인지 정확히 이해하지 못합니다. 불완전한 유형은 "누락 된"유형이 아닙니다. Incompete 유형은 선언 되었지만 정의 되지 않은 유형입니다 (구조체 유형의 경우). 정의되지 않은 선언을 찾는 것은 쉽습니다. 누락 된 정의를 찾는 것에 관해서는 ... 컴파일러가 처음부터 오류를 일으킨 것이기 때문에 여기서 당신을 돕지 않을 것입니다.
C에서 불완전한 유형 오류의 주요 원인은 유형 이름의 오타로 인해 컴파일러가 한 이름을 다른 이름과 일치시키지 못하도록합니다 (예 : 선언을 정의에 일치시키는 경우). 그러나 컴파일러는 여기서 당신을 도울 수 없습니다. 컴파일러는 오타를 추측하지 않습니다.
이 오류는 일반적으로 구조체의 이름이 코드의 구조체 초기화와 다른 경우 표시되므로 일반적으로 c는 입력 한 구조체의 이름을 찾고 원래 구조체를 찾을 수없는 경우 일반적으로 나타납니다. 해당 포인터를 가리키는 포인터를 가리키면 오류가 표시됩니다.
A-솔루션
C 언어에 대해 말하자면, 다음 선언 코드가 해결책이 될 것이라는 사실을 방금 발견했습니다.
typedef struct ListNode
{
int data;
ListNode * prev;
ListNode * next;
} ListNode;
따라서 일반적으로 유형 정의와 구조체 이름 모두에 동일한 이름을 지정합니다.
typedef struct X
{
// code for additional types here
X* prev; // reference to pointer
X* next; // reference to pointer
} X;
B-문제가있는 샘플
다음 선언문을 gcc
실행할 때 컴파일러에서 다음 선언을 모두 불완전한 것으로 간주합니다 . ;
removed->next->prev = removed->prev;
그리고 오류 출력에보고 된 역 참조 코드에 대해 동일한 오류가 발생합니다.
>gcc Main.c LinkedList.c -o Main.exe -w
LinkedList.c: In function 'removeFromList':
LinkedList.c:166:18: error: dereferencing pointer to incomplete type 'struct ListNode'
removed->next->prev = removed->prev;
아래 나열된 두 헤더 파일 선언 모두에 대해 ;
typedef struct
{
int data;
ListNode * prev;
ListNode * next;
} ListNode;
Plus this one;
typedef struct ListNodeType
{
int data;
ListNode * prev;
ListNode * next;
} ListNode;
Outside of possible scenarios involving whole-program optimization, the code code generated for something like:
struct foo *bar;
struct foo *test(struct foo *whatever, int blah)
{
return blah ? whatever: bar;
}
will be totally unaffected by what members struct foo
might contain. Because make utilities will generally recompile any compilation unit in which the complete definition of a structure appears, even when such changes couldn't actually affect the code generated for them, it's common to omit complete structure definitions from compilation units that don't actually need them, and such omission is generally not worthy of a warning.
A compiler needs to have a complete structure or union definition to know how to handle declarations objects of the type with automatic or static duration, declarations of aggregates containing members of the type, or code which accesses members of the structure or union. If the compiler doesn't have the information needed to perform one of the above operations, it will have no choice but to squawk about it.
Incidentally, there's one more situation where the Standard would allow a compiler to require a complete union definition to be visible but would not require a diagnostic: if two structures start with a Common Initial Sequence, and a union type containing both is visible when the compiler is processing code that uses a pointer of one of the structure types to inspects a member of that Common Initial Sequence, the compiler is required to recognize that such code might be accessing the corresponding member of a structure of the other type. I don't know what compilers if any comply with the Standard when the complete union type is visible but not when it isn't [gcc is prone to generate non-conforming code in either case unless the -fno-strict-aliasing
flag is used, in which case it will generate conforming code in both cases] but if one wants to write code that uses the CIS rule in such a fashion as to guarantee correct behavior on conforming compilers, one may need to ensure that complete union type definition is visible; failure to do so may result in a compiler silently generating bogus code.
참고URL : https://stackoverflow.com/questions/2700646/dereferencing-pointer-to-incomplete-type
'development' 카테고리의 다른 글
최고의 CSS 컬러 휠 사이트 (0) | 2020.12.05 |
---|---|
Entity Framework 무 신임 투표-.NET 4와 관련이 있습니까? (0) | 2020.12.05 |
함수 인수의 배열 길이 (0) | 2020.12.05 |
arm-linux-gcc와 arm-none-linux-gnueabi의 차이점은 무엇입니까? (0) | 2020.12.05 |
Uint8Array와 Uint8ClampedArray의 차이점 (0) | 2020.12.05 |