Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refactoring C++ code to use forward declarations

I've got a largeish codebase that's been around for a while and I'm trying to tidy it up a bit by refactoring it. One thing I'd like to do is find all the headers where I could forward declare members, instead of including the entire header file.

This is a fairly labour intensive process and I'm looking for a tool that could help me figure out which headers have members that could be forward declared.

Is there a compiler setting that could emit a warning or suggestion that the following code could use a forward declaration? I'm using the following compilers icc, gcc, sun studio and HP's aCC

Is there a standalone tool that could do the same job?

#include "Foo.h"
...//more includes

class Bar {
.......
private:
    Foo* m_foo;
};
like image 538
Glen Avatar asked Feb 19 '10 16:02

Glen


People also ask

Does C support forward declaration?

In Objective-C, classes and protocols can be forward-declared if you only need to use them as part of an object pointer type, e.g. MyClass * or id<MyProtocol>.

Why are forward declarations bad?

Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change. A forward declaration may be broken by subsequent changes to the library.

Why should I use forward declarations?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

Where do you put forward declarations?

Generally you would include forward declarations in a header file and then include that header file in the same way that iostream is included.


1 Answers

Anything involving the precise analysis of C++ requires essentially an entire C++ front end somewhere (otherwise you won't get answers, or they'll be wrong, and that works badly when you have "largish" applications). There aren't many practical answers available here.

Already mentioned is GCCXML is a GCC-derived package, so it has the requisite C++ front end. It produces XML, thus it will produce a LOT of output that you'll have to read back in to form "the in memory data structure" suggested in another answer. Its unfortunate that GCCXML builds that memory data structure already, then exports it as XML, and forces you to build it again. Of course, you could just use GCC, which builds the in memory data structure, but then you have to hack GCC to be what you want, and it really, really wants to be a compiler. That means you'll have a fight on your hands to bend it to your will (and explains why GCCXML exists: most people don't want that fight).

Not mentioned is the Edison Design Group C++ (EDG) front end, which builds that in memory data structure directly. It is a front end; you'll have to do all the analysis stuff yourself but your task may be simple enough so that isn't hard.

The last solution I know is mine: C++ FrontEnd for DMS. DMS is foundation for building program analysis, and its C++ FrontEnd is a complete Front end for C++ (e.g., does everything the GCC and Edison front ends do: parsing, tree building, name/type resolution). And you'll have to code your special analysis much the way you would for GCCXML and EDG by walking over the "in memory" datastructures produced by DMS.

What is really different is that DMS could then be used to actually modify your source code by updating those in memory data structures, and regenerate compilable code from those memory structures, including the original comments.

like image 100
Ira Baxter Avatar answered Sep 20 '22 22:09

Ira Baxter