Keduanya harus menghasilkan kegunaan yang sama, bahkan jika satu dengan keterkaitan, bukan?
Tidak, tidak saat Anda mempertimbangkan file .c lain termasuk header yang sama. Jika definisi struktur tidak terlihat oleh kompiler, detail definisi tersebut tidak dapat digunakan. Sebuah deklarasi tanpa definisi (misalnya hanya struct s;
) menyebabkan kompilator gagal jika ada yang mencoba untuk melihat ke dalam struct s
, sementara masih mengizinkannya untuk, misalnya kompilasi struct s *foo;
(selama foo
tidak direferensikan nanti).
Bandingkan versi berikut dari api.h
dan 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; |
| } |
+---------------------------------+
Klien API ini bekerja dengan salah satu versi:
#include "api.h"
void good(struct s *foo)
{
api_func(foo, 123);
}
Yang ini mengaduk-aduk detail implementasi:
#include "api.h"
void bad(struct s *foo)
{
foo->internal = 123;
}
yang akan bekerja dengan versi "definisi dalam header", tetapi tidak dengan versi "definisi dalam implementasi", karena dalam kasus terakhir kompilator tidak memiliki visibilitas tata letak struktur:
$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$
Jadi, versi "definisi dalam implementasi" melindungi dari penyalahgunaan detail implementasi pribadi yang tidak disengaja atau disengaja.