Skip to content

Commit c7e42c2

Browse files
committed
docs: Add paragraph about circular includes to CODING_STYLE.md
1 parent e895a49 commit c7e42c2

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

docs/CODING_STYLE.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,74 @@ SPDX-License-Identifier: LGPL-2.1-or-later
234234
const char *input);
235235
```
236236
237+
- Please do not introduce new circular dependencies between header files.
238+
Effectively this means that if a.h includes b.h, then b.h cannot include a.h,
239+
directly or transitively via another header. Circular header dependencies can
240+
make for extremely confusing errors when modifying the headers, which can be
241+
easily avoided by getting rid of the circular dependency. To get rid of a
242+
circular header dependency, there are a few possible techniques:
243+
- Introduce a new common header with the declarations that need to be shared
244+
by both headers and include only this header in the other headers.
245+
- Move declarations around between the two headers so one header doesn't need
246+
to include the other header anymore.
247+
- Use forward declarations if possible to remove the need for one header to
248+
include the other. To make this possible, you can move the body of static
249+
inline functions that require the full definition of a struct into the
250+
implementation file so that only a forward declaration of the struct is
251+
required and not the full definition.
252+
253+
Bad:
254+
255+
```c
256+
// manager.h
257+
258+
typedef struct Manager Manager;
259+
260+
#include "unit.h"
261+
262+
struct Manager {
263+
Unit *unit;
264+
};
265+
266+
// unit.h
267+
268+
typedef struct Unit Unit;
269+
270+
#include "manager.h"
271+
272+
struct Unit {
273+
Manager *manager;
274+
};
275+
```
276+
277+
Good:
278+
279+
```c
280+
// manager.h
281+
282+
typedef struct Unit Unit;
283+
284+
typedef struct Manager {
285+
Unit *unit;
286+
} Manager;
287+
288+
// manager.c
289+
290+
#include "unit.h"
291+
292+
// unit.h
293+
294+
typedef struct Manager Manager;
295+
296+
typedef struct Unit {
297+
Manager *manager;
298+
} Unit;
299+
300+
// unit.c
301+
302+
#include "manager.h"
303+
```
304+
237305
- The order in which header files are included doesn't matter too
238306
much. systemd-internal headers must not rely on an include order, so it is
239307
safe to include them in any order possible. However, to not clutter global

0 commit comments

Comments
 (0)