Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header file inclusion static analysis tools?

A colleague recently revealed to me that a single source file of ours includes over 3,400 headers during compile time. We have over 1,000 translation units that get compiled in a build, resulting in a huge performance penalty over headers that surely aren't all used.

Are there any static analysis tools that would be able to shed light on the trees in such a forest, specifically giving us the ability to decide which ones we should work on paring out?

UPDATE

Found some interesting information on the cost of including a header file (and the types of include guards to optimize its inclusion) here, originating from this question.

like image 774
fbrereto Avatar asked Jul 13 '11 20:07

fbrereto


People also ask

Which tool is used for static code analysis?

SonarQube is the popular static analysis tool for continuously inspecting the code quality and security of your codebases and guiding development teams during code reviews. SonarQube is used for automated code review with CI/CD Integration.

Which is a type of C C++ static code analysis tool?

CppDepend is a commercial static code analysis tool for C++. It can complement other static code analysis tools quite easily as it focuses on analyzing and visualizing the code base architecture (for example, whether it is layered correctly, dependencies-wise), rather than on revealing errors.

What is Klocwork tool?

Klocwork is a static code analysis tool owned by Minneapolis, Minnesota-based software developer Perforce. Klocwork software analyzes source code in real time, simplifies peer code reviews, and extends the life of complex software.

How do you prevent multiple inclusions of header files?

To avoid multiple inclusions of the same header file we use the #ifndef, #define and #endif preprocessor directives. Just write the entire program in only file and include headers once only.


2 Answers

The output of gcc -w -H <file> might be useful (If you parse it and put some counts in) the -w is there to suppress all warnings, which might be awkward to deal with.

From the gcc docs:

-H

Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the #include stack it is. Precompiled header files are also printed, even if they are found to be invalid; an invalid precompiled header file is printed with ...x and a valid one with ...!.

The output looks like this:

. /usr/include/unistd.h .. /usr/include/features.h ... /usr/include/bits/predefs.h ... /usr/include/sys/cdefs.h .... /usr/include/bits/wordsize.h ... /usr/include/gnu/stubs.h .... /usr/include/bits/wordsize.h .... /usr/include/gnu/stubs-64.h .. /usr/include/bits/posix_opt.h .. /usr/include/bits/environments.h ... /usr/include/bits/wordsize.h .. /usr/include/bits/types.h ... /usr/include/bits/wordsize.h ... /usr/include/bits/typesizes.h .. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h .. /usr/include/bits/confname.h .. /usr/include/getopt.h . /usr/include/stdio.h .. /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h .. /usr/include/libio.h ... /usr/include/_G_config.h .... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stddef.h .... /usr/include/wchar.h ... /usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/include/stdarg.h .. /usr/include/bits/stdio_lim.h .. /usr/include/bits/sys_errlist.h Multiple include guards may be useful for: /usr/include/bits/confname.h /usr/include/bits/environments.h /usr/include/bits/predefs.h /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h /usr/include/bits/typesizes.h /usr/include/gnu/stubs-64.h /usr/include/gnu/stubs.h /usr/include/wchar.h 
like image 172
Spudd86 Avatar answered Sep 20 '22 11:09

Spudd86


If you are using gcc/g++, the -M or -MM option will output a line with the information you seek. (The former will include system headers while the latter will not. There are other variants; see the manual.)

$ gcc -M -c foo.c foo.o: foo.c /usr/include/stdint.h /usr/include/features.h \   /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \   /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \   /usr/include/bits/wchar.h 

You would need to remove the foo.o: foo.c at the beginning, but the rest is a list of all headers that the file depends on, so it would not be too hard to write a script to gather these and summarize them.

Of course this suggestion is only useful on Unix and only if nobody else has a better idea. :-)

like image 23
Nemo Avatar answered Sep 22 '22 11:09

Nemo