Skip to content

Commit 4317110

Browse files
committed
docs: Modify include ordering paragraph to order linux headers last
All linux headers include "libc-compat.h" which checks whether various glibc headers have already been included and if that's the case, sets various defines which instruct the other linux headers to skip defining various definitions themselves to avoid conflicts. Unfortunately, various glibc headers are missing similar checks, most notable <netinet/in.h> and <net/if.h>. This means that if the linux headers are included before the glibc ones, including the glibc ones will cause compilation errors due to redefining structs. Note that including the relevant glibc header before the corresponding linux header (e.g. <netinet/in.h> before <linux/in.h> is not sufficient, as all linux headers include libc-compat.h and libc-compat.h checks once (the first time it's included) which relevant glibc headers have been included by that point and sets in stone what the other linux headers will do when included. So if <linux/if_arp.h> is included first, followed by <netinet/in.h> followed by <linux/in.h>, parsing <linux/in.h> will still fail because <linux/if_arp.h> will include <linux/libc-compat.h>, which will check if <netinet/in.h> has already bee included, which isn't the case, and so it will instruct <linux/in.h> to define all its structs, which will cause redefinitions errors because <netinet/in.h> will also include all its structs. Even if glibc fixes its <netinet/in.h> header to not define structs that have already been defined by <linux/in.h>, the above scenario would still fail, as <linux/libc-compat.h> would still tell <linux/in.h> to define all its structs, and <netinet/in.h> would also still define all its structs as <linux/in.h> hasn't been included yet by the time <netinet/in.h> is included.
1 parent cf0f741 commit 4317110

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

docs/CODING_STYLE.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -344,15 +344,17 @@ SPDX-License-Identifier: LGPL-2.1-or-later
344344
}
345345
```
346346
347-
- The order in which header files are included doesn't matter too
348-
much. systemd-internal headers must not rely on an include order, so it is
349-
safe to include them in any order possible. However, to not clutter global
350-
includes, and to make sure internal definitions will not affect global
351-
headers, please always include the headers of external components first
352-
(these are all headers enclosed in <>), followed by our own exported headers
353-
(usually everything that's prefixed by `sd-`), and then followed by internal
354-
headers. Furthermore, in all three groups, order all includes alphabetically
355-
so duplicate includes can easily be detected.
347+
- systemd-internal headers must not rely on an include order, so that it is safe
348+
to include them in any order possible. To not clutter global includes, and to
349+
make sure internal definitions will not affect global headers, please always
350+
include the headers of external components first (these are all headers
351+
enclosed in <> except `<linux/*.h>` headers), followed by our own exported
352+
headers (usually everything that's prefixed by `sd-`), then followed by
353+
internal headers and finally end with any `<linux/*.h>` headers. Linux headers
354+
have to be included last as they are parsed differently depending on which
355+
glibc headers have already been included by the time the first linux header is
356+
parsed. Furthermore, in all four groups, all includes should be ordered
357+
alphabetically.
356358
357359
- Please avoid using global variables as much as you can. And if you do use
358360
them make sure they are static at least, instead of exported. Especially in

0 commit comments

Comments
 (0)