Re: RFC: rules for #include directives
| From: | Tim Düsterhus | Date: | Wed, 18 Jan 2023 21:19:50 +0000 |
| Subject: | Re: RFC: rules for #include directives | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-119337@lists.php.net to get a copy of this message | ||
Hi
On 1/18/23 21:37, Flávio Heleno wrote:
This may be a silly question, but in that case, wouldn't #ifdef guards keep the compiler from including/parsing a.h twice?It's complicated. Modern compilers may include an optimization for include guards (https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html), but those rules may only be applied fairly narrowly. I just recompiled gammasection.c in ext/random [1] which is a fairly simple file containing just a handful of files and traced the compiler with 'strace' for the 'openat' syscalls: In total 2488 openat syscalls (many of them resulting in ENOENT, because of multiple include paths) were performed by the compiler. Multiple of my system headers were opened several times, because the include guard optimization could not be applied to them. I'm also seeing duplicated PHP headers:
20 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h",
13 "/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h",
11 "/usr/include/x86_64-linux-gnu/bits/wordsize.h",
8 "/usr/include/x86_64-linux-gnu/bits/mathcalls.h",
6 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h",
5 "/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h",
4 "/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h",
3 "/usr/include/assert.h",
3 "./php-src/Zend/zend_hash.h",
3 "./php-src/Zend/zend.h",
2 "/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h",
2 "/usr/lib/gcc/x86_64-linux-gnu/9/include/mm_malloc.h",
2 "/usr/lib/gcc/x86_64-linux-gnu/9/include/emmintrin.h",
2 "/usr/include/x86_64-linux-gnu/bits/long-double.h",
2 "./php-src/Zend/zend_string.h",
2 "./php-src/Zend/zend_stream.h",
2 "./php-src/Zend/zend_stack.h",
[1] https://github.com/php/php-src/blob/master/ext/random/gammasection.c
When a.h is *not* required by any of b.h, c.h nor foo.c, I agree that it should *not* be included at all, but when any of them,Ideally the scope of each individual header would also be narrowed to reduce the number of required dependencies. Staying at the gammasection.c example from above: Ideally it should not be necessary to include the 20 kB zend_string.h twice, because the gammasection.c does not use strings at all. Likewise the 50 kB zend_hash.h is included three times and not used it all. With the amount of C files this adds up. Best regards Tim Düsterhus