LWN.net Logo

LCA: Lessons from 30 years of Sendmail

LCA: Lessons from 30 years of Sendmail

Posted Feb 7, 2011 19:13 UTC (Mon) by nix (subscriber, #2304)
In reply to: LCA: Lessons from 30 years of Sendmail by cmccabe
Parent article: LCA: Lessons from 30 years of Sendmail

You seem to be confused about how include files work in C and C++. The way they work is that each translation unit (that's .cpp file to you) has to scan through all the files included by that unit, recursively. There are no shortcuts and the compiler cannot cache this work.
Except that there are shortcuts and GCC does cache this work, and has for more than fifteen years. (e.g. you can skip even opening files more than once if they are entirely contained in include guards and the guards are not #undefed.)


(Log in to post comments)

LCA: Lessons from 30 years of Sendmail

Posted Feb 8, 2011 0:26 UTC (Tue) by cmccabe (guest, #60281) [Link]

Sigh. I knew I was going to get some grief when I said "there are no shortcuts." :)

It depends on what you call a shortcut I guess. The header guard optimization is good, but the process as a whole is still O(n^n). Doing slightly more efficient things with file descriptors can't change that.

LCA: Lessons from 30 years of Sendmail

Posted Feb 8, 2011 18:27 UTC (Tue) by nix (subscriber, #2304) [Link]

Um, for 'slightly more efficient things with file descriptors' substitute 'almost always avoid parsing the vast majority of headers more than once'.

The exponential explosion you refer to simply does not happen with real code. And if header parsing is slow, GCC supports precompiled headers on common platforms to speed things up. (Yes, you may have to restructure your headers a bit to use them, but if you're compiling slow enough that you need this feature, that's a small cost.)

LCA: Lessons from 30 years of Sendmail

Posted Feb 11, 2011 9:33 UTC (Fri) by cmccabe (guest, #60281) [Link]

See my comment below. Basically, private data members of a class also need to be #included in that class' header file. So you *cannot* "avoid parsing the vast majority of headers more than once."

Under ideal conditions, C++ compilation is slow. If you add even a few non-ideal conditions, like programmers who love to define functions in header files "for performance", extensive use of templates, auto-generated anything, or unecessary cross-module dependencies, it becomes positively glacial.

Unfortunately real-world projects tend to have some or all of these conditions. I'm too lazy to find the reference now, but Google's C++ compile times are said to be measured in hours. And those guys read Effective C++ and know their stuff.

Precompiled headers sound helpful, but only for headers you are including from external libraries. Maybe they would be useful for something like QT? I haven't used precompiled headers.

LCA: Lessons from 30 years of Sendmail

Posted Feb 19, 2011 0:24 UTC (Sat) by nix (subscriber, #2304) [Link]

Er, when I said 'more than once' I said 'more than once per translation unit', and this is almost universal. This reduces your claimed O(n^2) to, uh, O(nm) where n is the number of translation units and m is the number of headers.

Precompiled headers are useful in any project where you have one great big header that #includes a lot of stuff. This is extremely common.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds