Tool to determine which headers are needed/not_needed?

C

C_guy

Does anyone know of a (hopefully free) tool that can traverse a
project and determine which "#include"s are not needed or needed in
every .C file? This would be helpful in removing header inclusions
that are redundant and/or unnecessary.

Thanks!
 
C

CBFalconer

C_guy said:
Does anyone know of a (hopefully free) tool that can traverse a
project and determine which "#include"s are not needed or needed
in every .C file? This would be helpful in removing header
inclusions that are redundant and/or unnecessary.

Use your editor. Comment out a #include statement. Recompile. If
no errors appear, that statement can go. If errors appear, remove
the comment. Repeat.
 
B

Barry Schwarz

Does anyone know of a (hopefully free) tool that can traverse a
project and determine which "#include"s are not needed or needed in
every .C file? This would be helpful in removing header inclusions
that are redundant and/or unnecessary.

If you start with none, the compiler will tell every time it
encounters something that would have been in a header. Add one at a
time till the diagnostics disappear.

Other than a pretty small time penalty, including an unnecessary
header or two usually doesn't cause problems.
 
R

robertwessel2

Use your editor.  Comment out a #include statement.  Recompile.  If
no errors appear, that statement can go.  If errors appear, remove
the comment.  Repeat.


Surely that's too simplistic - consider a header containing:

#undef FOO
#define FOO 17

Assuming a prior definition of FOO (to something other than 17), one
could easily see the compilation succeed, yet no longer be producing
the correct program).

Or a header that contains:

int a=1;

And everywhere else (possibly in the same compilation unit, if needed)
there's:

int a;

Many other potential problems exist

Which is not to say that sort of things is good programming practice
(and frankly most dependencies like that probably reflect poor
design), but we've all seen really bizarre stuff in headers, no?
 
F

Flash Gordon

Surely that's too simplistic - consider a header containing:

#undef FOO
#define FOO 17

Assuming a prior definition of FOO (to something other than 17), one
could easily see the compilation succeed, yet no longer be producing
the correct program).

Or a header that contains:

int a=1;

And everywhere else (possibly in the same compilation unit, if needed)
there's:

int a;

Many other potential problems exist

A far more likely potential problem in my opinion is if the header contains:
double foo(...)

Then with the default options on a lot of compilers (or with C89
conformance added to the defaults) the compiler will *not* complain, it
will just silently compiler the code with what is now undefined
behaviour which may or may not work. If foo currently returns an int it
is even worse, because then (if the parameters are not a problem) it
*will* work until foo() the return type of foo is changed.
Which is not to say that sort of things is good programming practice
(and frankly most dependencies like that probably reflect poor
design), but we've all seen really bizarre stuff in headers, no?

You don't need bizarre stuff in the header for commenting it out to
silently cause problems. Simple good practice can do it.

The OP would be well advised to ensure that the compiler is told to warn
about functions being called without a prototype in scope, and as much
else as possible. This will help catch problems where a header is *not*
included (directly or indirectly) but is needed. How to do this (and if
it is possible) is compiler dependant and so should be asked on a group
dedicated to the compiler.
 
I

Ian Collins

Jack said:
I see you've already got a few recommendations for the comment out and
look for errors school of thought, which does work but can take an
enormous amount of time for a large source code base.

The only tool that I know of that does this, and really well, is not
free. PC-Lint, http://www.gimpel.com. This feature is really a nice
little bonus. Its code checking function alone is worth many times
its price to anyone producing professional code.
I hadn't looked before, but Sun Studio lint (which is free) also reports
unnecessary headers.
 
A

Amandil

Use your editor.  Comment out a #include statement.  Recompile.  If
no errors appear, that statement can go.  If errors appear, remove
the comment.  Repeat.

That won't necessarily accomplish what the OP is trying to do. For
example:
/* Begin file: */
#include <stdarg.h>

int main()
{
puts("Hello, World");
return EXIT_SUCCESS;
}
/* End of file */

The above program will flag exactly 1 error, EXIT_SUCCESS not having
been
#define'd. #include'ing <stdlib.h> will fix that. The OP wants this
tool to
remind him to also #include <stdio.h>, and notify him that <stdarg.h>
is
unnecessary. Compiling with -Wall (or whatever it is on other
compilers) will
_warn_ me about the missing declaration for puts() (Which I may or may
not remember
is in <stdio.h>), but it won't make a peep about the extra header.

Mr. Klein helpfully mentioned a tool which may help you.

-- Marty Amandil
 
C

CBFalconer

Amandil said:
That won't necessarily accomplish what the OP is trying to do. For
example:
/* Begin file: */
#include <stdarg.h>

int main()
{
puts("Hello, World");
return EXIT_SUCCESS;
}
/* End of file */

The above program will flag exactly 1 error, EXIT_SUCCESS not
having been #define'd. #include'ing <stdlib.h> will fix that. The
OP wants this tool to remind him to also #include <stdio.h>, and
notify him that <stdarg.h> is unnecessary. Compiling with -Wall
(or whatever it is on other compilers) will _warn_ me about the
missing declaration for puts() (Which I may or may not remember
is in <stdio.h>), but it won't make a peep about the extra header.

No, C_guy wants to know what he can delete. Your suggestion above
will produce errors for the puts and the EXIT_SUCCESS usage.
Removing the include of stdarg.h will not affect that.

When something is undefined, most systems have an easy way to
access help on that item, which will specify the include file to
use. For example:

puts
====

Syntax
------
#include <stdio.h>

int puts(const char *string);

and you can always search the C standard for the same information.
The text version is very handy for this. Available (bzip2
compressed) at:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>
 
H

Harald van Dijk

Amandil said:
CBFalconer said:
C_guy wrote:

Does anyone know of a (hopefully free) tool that can traverse a
project and determine which "#include"s are not needed or needed in
every .C file? This would be helpful in removing header inclusions
that are redundant and/or unnecessary.

Use your editor. Comment out a #include statement. Recompile. If no
errors appear, that statement can go. If errors appear, remove the
comment. Repeat.

That won't necessarily accomplish what the OP is trying to do. For
example:
/* Begin file: */
#include <stdarg.h>

int main()
{
puts("Hello, World");
return EXIT_SUCCESS;
}
/* End of file */

[snip]

No, C_guy wants to know what he can delete. [snip]

Fine, then given

/* Begin file: */
#include <stdio.h>

int main()
{
puts("Hello, World");
return 0;
}
/* End of file */

are you saying C_guy wants the inclusion of <stdio.h> to go?
 
K

Keith Thompson

CBFalconer said:
and you can always search the C standard for the same information.
The text version is very handy for this. Available (bzip2
compressed) at:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>

No, the C standard is not available as a text version.

n869_txt.bz2 is a pre-standard draft. n1256.pdf is the latest
post-standard draft, or the standard itself is available (but not
free) via ANSI or ISO.
 
R

Richard

Keith Thompson said:
No, the C standard is not available as a text version.

n869_txt.bz2 is a pre-standard draft. n1256.pdf is the latest
post-standard draft, or the standard itself is available (but not
free) via ANSI or ISO.

You must have mentioned this to Chuckles about 1000 times by now. Please
stop replying to his SPAM and thus waking up threads he pollutes for the
rest of us.
 
F

Flash Gordon

CBFalconer wrote, On 11/09/08 22:53:
No, C_guy wants to know what he can delete. Your suggestion above
will produce errors for the puts and the EXIT_SUCCESS usage.

Not if the OP is compiling with C89, the most commonly implemented
standard, or something close to C89 which is the most common default
mode for compilers. In such a situation there is no diagnostic required
for the call to puts. It is only with C99 the a diagnostic (which might
not be an error) is required.
Removing the include of stdarg.h will not affect that.

That was part of Amadil's point!
When something is undefined, most systems have an easy way to
access help on that item, which will specify the include file to
use. For example:

True but irrelevant. There is no requirement on the commonly implemented
standard to diagnose the lack of a declaration.
and you can always search the C standard for the same information.
The text version is very handy for this. Available (bzip2
compressed) at:

<http://cbfalconer.home.att.net/download/n869_txt.bz2>

Please at least tell people that is not any version of the standard and
where they can find something that does actually represent the standard.
It has been pointed out to you before that there are significant
differences.
 
C

CBFalconer

Harald said:
CBFalconer wrote:
.... snip ...
No, C_guy wants to know what he can delete. [snip]

Fine, then given

/* Begin file: */
#include <stdio.h>

int main()
{
puts("Hello, World");
return 0;
}
/* End of file */

are you saying C_guy wants the inclusion of <stdio.h> to go?

No, he wants to know if it CAN BE removed.
 
B

Ben Bacarisse

CBFalconer said:
Use your editor. Comment out a #include statement. Recompile. If
no errors appear, that statement can go. If errors appear, remove
the comment. Repeat.

That does not work if a pair (or more) of include files need each
other but are (together) not needed by the rest of the code. This is
poor design, but a robust method should be able to detect it.
 
C

CBFalconer

Ben said:
That does not work if a pair (or more) of include files need each
other but are (together) not needed by the rest of the code. This is
poor design, but a robust method should be able to detect it.

I believe this is not allowed with standard C system headers.
 
R

robertwessel2

CBFalconer said:



What is the basis for your belief?


7.1.2 implies it. The standard headers are basically independent, can
be included in any order, and can be included multiple times, without
altering their meaning. A minor except exists for assert.h.

But I don’t think the OP was limiting the discussion to the standard
headers.
 
J

jacob navia

C_guy said:
Does anyone know of a (hopefully free) tool that can traverse a
project and determine which "#include"s are not needed or needed in
every .C file? This would be helpful in removing header inclusions
that are redundant and/or unnecessary.

Thanks!

The lcc-win compiler will output all files included
in a given source file using the

lcc -M

option. If you collect this output in a series of files
you will (implicitely) obtain which files are NOT needed
since they will not appear in that list.
 
N

Nick Keighley

C_guy wrote:

Use your editor.  Comment out a #include statement.  Recompile.  If
no errors appear, that statement can go.  If errors appear, remove
the comment.  Repeat.

[-] Search for #include: (40261 results found in 9365 files)
 
K

Keith Thompson

jacob navia said:
The lcc-win compiler will output all files included
in a given source file using the

lcc -M

option. If you collect this output in a series of files
you will (implicitely) obtain which files are NOT needed
since they will not appear in that list.

I don't think that addresses the OP's question.

A concrete example:

#include <stdio.h>
#include <math.h>
int main(void)
{
puts("Hello, world");
return 0;
}

The OP is looking for a tool that will tell him that the
"#include <math.h>" is not needed.

lcc -M, if I understand it correctly, can tell you which headers are
not #include'd; it can't tell you which headers are #include'd
unnecessarily.
 
I

Ian Collins

Keith said:
I don't think that addresses the OP's question.

A concrete example:

#include <stdio.h>
#include <math.h>
int main(void)
{
puts("Hello, world");
return 0;
}

The OP is looking for a tool that will tell him that the
"#include <math.h>" is not needed.

lcc -M, if I understand it correctly, can tell you which headers are
not #include'd; it can't tell you which headers are #include'd
unnecessarily.
Like this:

lint -Nlevel /tmp/x.c

include file is unnecessary
(2) /usr/include/math.h
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top