둘 다 연결에 의한 경우에도 동일한 사용성을 가져야합니다. 그렇지 않습니까?
아니요, 동일한 헤더를 포함하는 다른 .c 파일을 고려할 때는 아닙니다. 구조 정의가 컴파일러에 표시되지 않는 경우 해당 정의의 세부 정보를 사용할 수 없습니다. 정의가없는 선언 (예 : just struct s;
)은 내부를 들여다 보려고하면 컴파일러가 실패 struct s
하게하고, 예를 들어 struct s *foo;
( foo
나중에 역 참조되지 않는 한) 여전히 컴파일을 허용합니다 .
api.h
및의 다음 버전을 비교하십시오 api.c
.
Definition in header: Definition in implementation:
+---------------------------------+ +---------------------------------+
| struct s { | | struct s; |
| int internal; | | |
| int other_stuff; | | extern void |
| }; | | api_func(struct s *foo, int x); |
| | +---------------------------------+
| extern void | +---------------------------------+
| api_func(struct s *foo, int x); | | #include "api.h" |
+---------------------------------+ | |
+---------------------------------+ | struct s { |
| #include "api.h" | | int internal; |
| | | int other_stuff; |
| void | | }; |
| api_func(struct s *foo, int x) | | |
| { | | void |
| foo->internal = x; | | api_func(struct s *foo, int x) |
| } | | { |
+---------------------------------+ | foo->internal = x; |
| } |
+---------------------------------+
이 API 클라이언트는 다음 버전 중 하나에서 작동합니다.
#include "api.h"
void good(struct s *foo)
{
api_func(foo, 123);
}
이것은 구현 세부 사항을 찌릅니다.
#include "api.h"
void bad(struct s *foo)
{
foo->internal = 123;
}
"definition in header"버전에서는 작동하지만 "definition in implementation"버전에서는 작동하지 않습니다. 후자의 경우 컴파일러는 구조의 레이아웃을 볼 수 없습니다.
$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$
따라서 "구현시 정의"버전은 개인 구현 세부 정보의 우발적 또는 고의적 오용으로부터 보호합니다.