gcc’s -MM option is nice for discovering just how large a seemingly innocent header’s dependency tree is. Given a tiny program like this:
#include "fugazi.h"
int main()
{
return 0;
}
you can run a script similar to the following:
#!/bin/sh
gcc -I/home/evadeflow/MMC/Model/include \
-I/home/evadeflow/MMC/VisObjectControl/include \
-I/home/evadeflow/MMC/Framework/include \
-I/home/evadeflow/MMC/Common/include \
-I/home/evadeflow/MMC/Xml/tinyxml \
-I/home/evadeflow/MMC/AniObject/include \
-I/home/evadeflow/MMC/Logger/include \
-I/home/evadeflow/MMC/VisualIO/include \
-DLINUX -DCCL_DLL -D_DEBUG -DFUGAZI_RELEASE_BUILD=1 -MM fakemain.cpp
and it will tell you exactly how many headers you’ve put yourself in bed with. Here’s a tip. If the output looks like this:
/home/evadeflow/MMC/AniObject/include/AniObjectCreator.h /home/evadeflow/MMC/AniObject/include/AniObjectDefinition.h /home/evadeflow/MMC/AniObject/include/AniObjectDefinitionLoader.h /home/evadeflow/MMC/AniObject/include/AniObjectTypes.h /home/evadeflow/MMC/AniObject/include/AninDefinition.h /home/evadeflow/MMC/Framework/include/replayIface.h /home/evadeflow/MMC/Framework/include/threeSpaceValue.h /home/evadeflow/MMC/Common/include/fugazi.h /home/evadeflow/MMC/Model/include/Animation.h /home/evadeflow/MMC/Model/include/Control.h /home/evadeflow/MMC/Model/include/External.h /home/evadeflow/MMC/Model/include/Object.h /home/evadeflow/MMC/Model/include/ObjectCreator.h /home/evadeflow/MMC/Model/include/State.h /home/evadeflow/MMC/Model/include/Update.h /home/evadeflow/MMC/VisualIO/include/visualIO_av_types.h /home/evadeflow/MMC/VisObjectControl/include/DOFBead.h /home/evadeflow/MMC/VisObjectControl/include/macros.h /home/evadeflow/MMC/VisObjectControl/include/SwitchNode.h /home/evadeflow/MMC/VisObjectControl/include/VisualObject.h /home/evadeflow/MMC/visObjectControl/include/VisualObjectPart.h
it means someone is Doing It Wrong. Thanks, but… I don’t really want or need a physical dependency on those other 21 headers. This is pretty far from the ideal of a ‘smallest possible contact surface’.
I don’t understand why so many otherwise competent programmers design interfaces this way, but it’s alarmingly common. I think it’s partly because so many OOP texts talk about encapsulation/information hiding only in the context of an object’s methods. Very few of them discuss why hiding objects entirely (i.e., minimizing physical dependencies) is so important. Lakos covers all the reasons, but his book’s almost twenty years old now, and contains a few anachronisms that put a lot of developers off. More’s the pity. It may be even more relevant today than it was when it was first published.

