Skip to main content
gamedev.net
🔒 Locked

C++ detecting unused functions and headers

Started by Storyyeller 15 replies 7.9k views
Original Post
Storyyeller
Storyyeller
Is there any free tool available to find unused headers and unused functions in a project? It seems like the compiler and linker should be able to do this but I can't find any options which would output the information.

By the way, I'm using Code::Blocks on Windows 7.
I trust exceptions about as far as I can throw them.
Calexus
Calexus
I don't know if its possible but maybe you can use gcov (?)
Exitus Acta Probat
Adam_42
Adam_42
Why do you want to find out which functions aren't used?

Unused functions (at least non-virtual ones) should be removed by the linker in release builds so there's no need to work out which ones aren't used as deleting them won't have much effect except maybe a small improvement in build times.

If you really need to do it try comparing map files created with the linker optimizations on and off (leave the compiler settings the same). That probably won't be perfect as the linker can also merge two functions into one, but it might be good enough. The map file may also contain mangled function names.
SriLumpa
SriLumpa

Why do you want to find out which functions aren't used?


Maybe not technically, but I find it very important for future reading to remove old code.
Storyyeller
Storyyeller
Well it can indicate mistakes or a need for refactoring.
I trust exceptions about as far as I can throw them.
GregMichael
GregMichael
The best free tool available is "Yourself"....if you wrote it...you should know what is and isn't needed.

Why would you need a tool to do this ???
wqking
wqking

The best free tool available is "Yourself"....if you wrote it...you should know what is and isn't needed.

Why would you need a tool to do this ???


For unused functions, it's true.

For unused headers, no. When you remove code, it's very hard to remember to check if any header should be removed too.
AAA
AAA
There are many valid reasons to do this. Working on large projects, across many DLLs you can see some benefits (beyond just improvements in build times) There are things the linker won't remove for you automatically... like exported methods/classes and soon enough you find that there is a lot of unused code.

I've once written a collection of batch files, that used little more than grep to "discover" header files that aren't used by cpp files (other than the corresponding cpp file) That gave a good indication of various classes that could be removed. It's not a fool proof way, and this sort of thing wouldn't catch everything.

I heard PCLint might be able to tell you about unused functions... but I may be wrong there.
hughiecoles
hughiecoles
The beauty of being a computer programmer is that you have the ability to write tools like this yourself.

Consider it a learning experience.
--------------------------------------Not All Martyrs See Divinity, But At Least You Tried
Antheus
Antheus
This problem isn't solvable using C++ alone. It simply does not define what "unused" means.

C++ toolchain is: pre-processor -> template expansion -> compiler -> linker

First two steps are text replacement, compiler converts text into individual symbols, linked joins symbols into something platform-specific. At no point does actual meaning of these matter. Strong decoupling is also the cause of obscure linker errors.

C++ also doesn't differentiate between code and data - it's perfectly valid to take some chunk of memory and run it as code or reinterpret it as something else.

Then there DLLs. Depending on which address is chosen, different functions will be ran.

These techniques are uncommon in application programming, but may be used in system programming. A general tool to find unused symbols simply doesn't exist because C++ does not standardize the toolchain nor does it have a standard ABI or build system. Language simply doesn't define what the final result is or how it's used.
Storyyeller
Storyyeller

The beauty of being a computer programmer is that you have the ability to write tools like this yourself.

Consider it a learning experience.


If I considered it feasible to do myself, I wouldn't have asked. But from what I've read, people have spent years unsuccessfully attempting to write C++ parsers. It's apparently extremely hard to do, and I doubt that C++0x is making things any easier.

The beauty of being a computer programmer is to know when to look for premade solutions.
I trust exceptions about as far as I can throw them.
the_edd
the_edd

If I considered it feasible to do myself, I wouldn't have asked. But from what I've read, people have spent years unsuccessfully attempting to write C++ parsers. It's apparently extremely hard to do, and I doubt that C++0x is making things any easier.


It's not that hard, really. Look for all #include statements. A regular expression will probably do just fine. Create a new version of a source file with a #include removed. Try to compile it. Use the success or failure of the compilation to decide whether or not to replace the original file with the modified one. Rinse and repeat.

I'd be a little bit careful of standard library headers though. Many implementations contain declarations for particular things in multiple headers even when the standard only guarantees that the declaration be present in a single particular header e.g. it's often the case that you get many standard manipulators such as std::endl from <iostream> even though it's not required. This might lead to the technically incorrect removal of <iomanip>.

You also have to watch out for differences between build configurations, so when you compile each version of a source file, do so in each configuration that matters to you.
magic_man
magic_man

I don't know if its possible but maybe you can use gcov (?)


QFT. I did rate this up yet either the rating is broken or someone felt it was bad advice.
"You insulted me!" I did not say that in the private message Tom Sloper!
Storyyeller
Storyyeller

It's not that hard, really. Look for all #include statements. A regular expression will probably do just fine. Create a new version of a source file with a #include removed. Try to compile it. Use the success or failure of the compilation to decide whether or not to replace the original file with the modified one. Rinse and repeat.

I'd be a little bit careful of standard library headers though. Many implementations contain declarations for particular things in multiple headers even when the standard only guarantees that the declaration be present in a single particular header e.g. it's often the case that you get many standard manipulators such as std::endl from <iostream> even though it's not required. This might lead to the technically incorrect removal of <iomanip>.

You also have to watch out for differences between build configurations, so when you compile each version of a source file, do so in each configuration that matters to you.


That might work for headers, but it doesn't help finding unused functions.
I trust exceptions about as far as I can throw them.
the_edd
the_edd

[quote name='edd²' timestamp='1301647903' post='4792962']
It's not that hard, really. Look for all #include statements. A regular expression will probably do just fine. Create a new version of a source file with a #include removed. Try to compile it. Use the success or failure of the compilation to decide whether or not to replace the original file with the modified one. Rinse and repeat.

I'd be a little bit careful of standard library headers though. Many implementations contain declarations for particular things in multiple headers even when the standard only guarantees that the declaration be present in a single particular header e.g. it's often the case that you get many standard manipulators such as std::endl from <iostream> even though it's not required. This might lead to the technically incorrect removal of <iomanip>.

You also have to watch out for differences between build configurations, so when you compile each version of a source file, do so in each configuration that matters to you.


That might work for headers, but it doesn't help finding unused functions.
[/quote]
Sorry(?)
Servant of the Lord
Servant of the Lord

Is there any free tool available to find unused headers and unused functions in a project? It seems like the compiler and linker should be able to do this but I can't find any options which would output the information.

By the way, I'm using Code::Blocks on Windows 7.

I recently started using a Perl script called cInclude2dot which required graphviz. I don't like installing too much junk on my computer, but I stilled graphviz and perl just for this, and it's totally worth it. It generates a huge PNG file that shows a graph of all your headers, and which ones include which other ones. It has been helping me reduce code dependency on other parts of my code, to make it more self-contained. Any "free floating" source files or headers are immediately noticeable because they are outside the main cluster of files shown in the graph in their own small cluster.

(Think of it: You probably don't have any *completely* unused headers, because 4 times out of 5, you probably have at least a mySource.cpp including your myHeader.cpp, and mySource and myHeader are both unused together, but wont be picked up by basic search. The solution above catches this easily, by visually separating the the files)

It feels a bit hackish/clumsy to me to use the tools (they are GNU-style programs) but it's not hard, and totally worth it.
My code dependencies made the graph look like a bowl of spaghetti.biggrin.gif So I've done some work on that in my code. It helps me if I come back with a paint program and fill the graph items to color code the files based on their namespace.
mrbastard
mrbastard
Include Manager is a great, cheap tool that may help you find unused headers.

For finding unused functions, I'd think about using dumpbin to find out what's actually being used and gccxml to get all the possible funcs names. Though I daresay gcov would be a better way to go.
[size="1"]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.