By the way, I'm using Code::Blocks on Windows 7.
🔒 Locked
C++ detecting unused functions and headers
Advertisement
Original Post
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.
By the way, I'm using Code::Blocks on Windows 7.
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.
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.
Well it can indicate mistakes or a need for refactoring.
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 ???
Why would you need a tool to do this ???
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.
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.
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.
The beauty of being a computer programmer is that you have the ability to write tools like this yourself.
Consider it a learning experience.
Consider it a learning experience.
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.
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.
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.
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.
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 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(?)
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.
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.
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.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement