Using #include for .cxx files

I've seen this a lot in code created by people who learned C++ while working with ROOT.

Say you're working on a project main.cxx and you want to use some functions / classes in another file, other.cxx. You could copy and paste this code into your routine, but it it could be hundreds or thousands of lines long, and you probably don't want to crowd your file with lots of code you're never going to edit. It makes a lot more sense to keep other.cxx in one file, and your own work in another. One easy way to do this is using #include other.cxx in main.cxx. The result looks like this.

I've color-coded #include statements, compiling , and linking .

DirectedGraphPlugin_1.png diagram

This gets the job done, but it's not the 'proper' way to do things. According to the C++ community, what you should be doing is

DirectedGraphPlugin_2.png diagram

There are two reasons for this. The less important reason is to save time: if your makefile is properly set up, you'll only have to recompile main.cxx after you edit it, and then relink main.o and other.o. In general, linking is fast, whereas recompiling other.cxx, especially if it's a big file, could take a while. If you go with the first approach, you're going to have to recompile other.cxx every time.

The second (probably) more important reason to avoid the first (improper) approach is that it's dangerous.

Why? Well, let's see what happens when both main.cxx and other.cxx use some common utility util.cxx. In the second (proper) case, we get DirectedGraphPlugin_3.png diagram

It looks more complicated, but this is no problem: the code for each .o file is compiled separately. When main.o is compiled, it will be aware of the functions declared in util.hh, but it won't have any idea how these functions work until the three objects are linked, at which point the linker will link declarations of functions in util.hh to the compiled functions in util.o.

Lets see what happens when we try to add util.cxx under the first paradigm:

DirectedGraphPlugin_4.png diagram

All hell breaks loose because the linker will see multiple definitions of the same functions in util.cxx, since it's #included twice (once in main.cxx and once in other.cxx). C++ isn't happy when you doubly define a function / class.

There are ways around this, of course, but they are all ugly and not recommended click here to see them Close You could edit main.cxx and remove the #include util.cxx, but you'll have to remember to put it back in if you ever stop using other.cxx. Maybe not such a big deal for one utility, but try to imagine the confusion if you use several utilities and several routines in your main.cxx: you'll have to keep track of a tree of files, making sure each is included once and only once.

You could also automate this process by using so called "header guards",

#ifndef OTHER_CXX
#define OTHER_CXX

// your source code here

but putting header guards around your source code seems like a bit of a hack, and will certainly confuse anyone who reads your code.

Things are probably easier if you do them 'properly'. In this case, if you want to remove other.cxx you can simply comment out #include other.hh in main.cxx and remove other.o from the list of files to link when building main.

The choice is yours, of course, but keep in mind that the method I'm advocating here is (with very few exceptions) the standard in the C++ community. If you choose to do things your own way, you're using a tool in a way it was never designed to be used---it's ok in a pinch, but you shouldn't make it the norm.

-- DanielGuest - 20-Mar-2011

Edit | Attach | Watch | Print version | History: r6 < r5 < r4 < r3 < r2 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r6 - 2013-08-29 - TWikiGuest
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    Sandbox All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
or Ideas, requests, problems regarding TWiki? use Discourse or Send feedback