Boost logo

Boost :

From: Dan Muller (q266e1d02_at_[hidden])
Date: 2003-09-09 10:42:34


I know that the "#pragma once" issue has been debated on this list in
the past, but I would like to bring it up again because of problems I'm
having with a project at work.

Our application is a large bookkeeping program with various internal
layers to isolate the database handling from the user interface, and
with a non-trivial proprietary UI framework that binds the database
layers to MFC code. We're using VC7.1 and boost 1.30.0. One of the
database layers defines a number of classes to represent the contents of
database fields. I recently modified some of these classes to use boost
code. (Specifically, I'm making use of the date and date-time libraries,
but that's not particularly relevant.)

Our builds have slowed down a lot, and it took me a while to determine
why. I wrote some Perl scripts that would run our .cpp files through the
preprocessor and analyze the resulting #line directives. (A very slow
way to do this, but very accurate.)

I analyzed one project carefully, the one that defines the UI framework.
It also makes heavy use of the database layer's generic parts. It was
indirectly including boost\config.hpp 6.931 times per .cpp file in the
project -- all due to indirect use of boost through the database
subsystem. There are even pieces of the mpl included, even though we
don't directly use it in our own code. (boost\mpl\aux_\config
\overload_resolution.hpp, 0.99 times per .cpp file.)

One of our developers tried gathering all of the boost includes from the
database layer into one header file, to which he also added a "pragma
once". He replaced all boost-related includes with a reference to this
file. Finally, he included this file in the UI-level project's
precompiled headers. Build time was reduced by half. Similar reductions
(one-third to one-half) have been noted in other projects affected by
this. I'm not particularly happy with this solution from a maintenance
perspective, though.

Now, obviously, there are a couple of things going on here. Precompiling
helps a lot. But unless very strict discipline is used in adding
inclusions, the precompiled header mechanism won't prevent multiple
inclusions of files. Although include guards help, they don't help
enough -- the sheer time involved in looking a file up and reading it
hurts, as Lakos has demonstrated. There have been previous discussions
on this list that talked about other shortcomings with the include garud
idiom, related to choosing the preprocessor symbol to use. So even if a
compiler, like gcc, recognizes the idiom and gives it special handling,
there are still shortcoming to this tradition.

It would be really helpful to those of us working with VC if boost
developers were encouraged to use #pragma once, suitably guarded. I
would think that a global boost configuration setting, defaulted
appropriately per compiler, could be used to guard it.

Thanks for listening...

-- 
Dan Muller
"So that's what an invisible barrier looks like!" (Time Bandits)

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk