Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should struct definitions go in .h or .c file?

Tags:

c

struct

header

People also ask

Do struct definitions go in header file?

Structs should be defined in headers, unless they are local to specific file — a special occasion, prefer to define them in header, you can easily move them to implementation file later if needed.

Where should I define struct in C?

If the struct definition is needed from multiple . c files then it should go in the header, otherwise it doesn't have to. @M.M It is only needed in one . c file.

Does a .c file need a .h file?

c file can include the . h file for the functions it needs, and won't need to be recompiled if a header file it didn't include got changed.

Should includes be in header or C?

c') should include them itself, and not rely on its header to include them. The header should only include what users of the software need; not what the implementers need.


Private structures for that file should go in the .c file, with a declaration in the .h file if they are used by any functions in the .h .

Public structures should go in the .h file.


Both should result in the same usability, even if one is by linkage, shouldn't they?

No, not when you consider other .c files including the same header. If the definition of the structure is not visible to the compiler, the details of that definition cannot be used. A declaration without a definition (e.g. just struct s;) causes the compiler to fail if anything tries to look inside struct s, while still allowing it to e.g. compile struct s *foo; (as long as foo is not later dereferenced).

Compare these versions of api.h and 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;          |
                                      | }                               |
                                      +---------------------------------+

This client of the API works with either version:

#include "api.h"

void good(struct s *foo)
{
    api_func(foo, 123);
}

This one pokes around in the implementation details:

#include "api.h"

void bad(struct s *foo)
{
    foo->internal = 123;
}

which will work with the "definition in header" version, but not with the "definition in implementation" version, as in the latter case the compiler has no visibility of the layout of the structure:

$ gcc -Wall -c bad.c
bad.c: In function 'bad':
bad.c:5: error: dereferencing pointer to incomplete type
$

So, the "definition in implementation" version protects against accidental or deliberate misuse of private implementation details.


If the struct is to be used by other compilation units (.c files) , place it in the header file so you can include that header file wherever it is needed.

If the struct is only used in one compilation unit (.c file), you place it in that .c file.


The point is, placing it in a header file allows you to use the structure (or any other definition) from multiple source files, just by including that header file.

But if you are sure it will only be used from one source file, then it really doesn't make any difference.


I put them into the C file to make it more Object Oriented, see this article.