GNOME Bugzilla – Bug 689810
Include guard optimization
Last modified: 2018-05-16 12:51:59 UTC
Created attachment 230918 [details] header edit script GCC and other C compilers have optimizations for multiple inclusions of header files that are contained entirely in an #ifndef/#endif pair [1]. Unfortunately, most of GTK+'s header files use the following pattern, with the __GTK_H_INSIDE__ check outside the guards, which disables the optimization: #if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) #error "Only <gtk/gtk.h> can be included directly." #endif #ifndef __GTK_COLOR_SELECTION_DIALOG_H__ #define __GTK_COLOR_SELECTION_DIALOG_H__ The check can be safely moved inside the guards. My test program contains just the GTK+ include directive: $ cat test.c #include <gtk/gtk.h> Before any changes, compilation (i.e. parsing the GTK+ includes) required about 355ms (best of 10 runs): before$ time gcc -c `pkg-config --cflags gtk+-3.0` test.c real 0m0.355s user 0m0.284s sys 0m0.060s After making this change in the GTK+, GLib, ATK and GDK-pixbuf headers, compilation was about 100ms faster: after$ time gcc -c `pkg-config --cflags gtk+-3.0` test.c real 0m0.252s user 0m0.196s sys 0m0.048s I've attached the script I've used to make this change. It can be run using the command: find repo/ -name '*.h' -exec perl fix-guard.pl {} + [1] http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
Created attachment 230919 [details] [review] GTK+ 3 patch
Created attachment 230920 [details] [review] GTK+ 2 patch
Created attachment 230921 [details] [review] GLib patch
Created attachment 230922 [details] [review] GDK-pixbuf patch
Created attachment 230923 [details] [review] ATK patch
Review of attachment 230923 [details] [review]: Looks good. Commit it please.
Running Peter's script on current ATK also works fine. Maybe we can land this?
Comment on attachment 230923 [details] [review] ATK patch I reran the script to produce an equivalent commit, and pushed it to master after getting an ack from Emmanuele on IRC.
I proposed doing this for WebKit a while back, but Carlos Garcia pointed out that it is simply wrong. Consider that it breaks the single-include guard. Doesn't that now only work the *first* time the header is included? So: #include <atk.h> #include <atk/atksomething.h> would no longer produce a build failure, right?