detect necessary #includes

S

Steven Woody

hi,

after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary. is there any tool which can find out those "#include"s
and tell me it's safe to remove them? manual work is so time consuming.
thanks.

-
woody
 
L

Logan Shaw

Steven said:
hi,

after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary. is there any tool which can find out those "#include"s
and tell me it's safe to remove them? manual work is so time consuming.

Only a standards document or other API documentation can really tell
you whether it's safe to remove a #include.

Consider what happens if some documentation says this:

"foo() is available in foo.h, and bar() is available in bar.h".

Then suppose that foo.h and bar.h both contain this:

#include <foobar.h>

and that foobar.h contains the prototypes for both foo() and bar().

Now let's suppose that your code uses both foo() and bar(), and you,
by trial and error, determine you can get away by only including
foo.h, and you remove the include for bar.h. It will compile OK
right now, but what happens later on when the foobar library that
you're using changes its implementation so that foo()'s prototype
is really in foo.h and bar()'s prototype is really in bar.h? You
will have created for yourself a horrible mess because your #includes
are depending on quirks of the .h files which aren't guaranteed
rather than depending on what is guaranteed by the documentation.

More to the point, how can any automated program that just looks
at header files tell which header files are the ones that the
documentation guarantees will work?

I suppose it might be possible in some limited cases to write such
a tool, such as if no .h file every includes another .h file, but
that's not how most .h files usually work...

- Logan
 
S

Steven Woody

Logan said:
Only a standards document or other API documentation can really tell
you whether it's safe to remove a #include.

Consider what happens if some documentation says this:

"foo() is available in foo.h, and bar() is available in bar.h".

Then suppose that foo.h and bar.h both contain this:

#include <foobar.h>

and that foobar.h contains the prototypes for both foo() and bar().

Now let's suppose that your code uses both foo() and bar(), and you,
by trial and error, determine you can get away by only including
foo.h, and you remove the include for bar.h. It will compile OK
right now, but what happens later on when the foobar library that
you're using changes its implementation so that foo()'s prototype
is really in foo.h and bar()'s prototype is really in bar.h? You
will have created for yourself a horrible mess because your #includes
are depending on quirks of the .h files which aren't guaranteed
rather than depending on what is guaranteed by the documentation.

More to the point, how can any automated program that just looks
at header files tell which header files are the ones that the
documentation guarantees will work?

I suppose it might be possible in some limited cases to write such
a tool, such as if no .h file every includes another .h file, but
that's not how most .h files usually work...

- Logan

i am not going to remove any standard or system wide #includes, i am
going to remove those #includes which include my own headers.
 
?

=?ISO-8859-1?Q?Bj=F8rn_Augestad?=

Steven said:
hi,

after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary. is there any tool which can find out those "#include"s
and tell me it's safe to remove them? manual work is so time consuming.
thanks.

-
woody

PC-lint(www.gimpel.com) does that, IIRC.
Bjørn
 
R

Richard Heathfield

Steven Woody said:
hi,

after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary. is there any tool which can find out those "#include"s
and tell me it's safe to remove them? manual work is so time consuming.
thanks.

Remove all your headers, and recompile. Then see what the compiler moans
about. This may also help you to refactor your headers in a more sensible
way.
 
M

Mark McIntyre

hi,

after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary. is there any tool which can find out those "#include"s
and tell me it's safe to remove them? manual work is so time consuming.

Well, you could us an cross-ref tool to build up a list of which
functions are used and which #include they come from, then by process
of elimination work out which ones you don't need. If you have a many
MLOC legacy project split into dozens of libs, thats how I'd do it.

However for a project you've been working on for only weeks, it would
be quicker to just comment out any header you don't think you need,
recompile and watch the warnings.
Mark McIntyre
 
S

Steven Woody

Richard said:
Steven Woody said:


Remove all your headers, and recompile. Then see what the compiler moans
about. This may also help you to refactor your headers in a more sensible
way.

thanks for all your advices. commenting out all headers then add one by
one seems the only solution i can adapt thought i wish there exists a
more time saving method. pc-lint is not suite to me since i am working
on Linux. thanks again.
 
E

Emmanuel Delahaye

Steven Woody a écrit :
after some weeks of development of a project, there likely are many
"#include" in source files which was added before but are now
unnecessary.

Who knows ? Things can change and the guards are doing their job. Don't
touch anything. You'll gain peanuts.
 
R

Richard Heathfield

Steven Woody said:
thanks for all your advices. commenting out all headers

Please, please, please don't do this. If you want to rip them out
temporarily, do it like so:

#if 0
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quux.h"
#endif

Then, as you discover you need them, fish them out of the #if and into the
code proper.

Comment syntax is for adding something extra to the code, not for taking
something away.
 
S

Steven Woody

Richard said:
Steven Woody said:


Please, please, please don't do this. If you want to rip them out
temporarily, do it like so:

#if 0
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quux.h"
#endif

i've not seen big difference between this method and that of commting.
Then, as you discover you need them, fish them out of the #if and into the
code proper.

Comment syntax is for adding something extra to the code, not for taking
something away.

how to understand this ? i am so interesting
 
E

Emmanuel Delahaye

Richard Heathfield a écrit :
#if 0
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quux.h"
#endif

Then, as you discover you need them, fish them out of the #if and into the
code proper.

"fish them out"

I like it !
 
R

Richard Heathfield

Steven Woody said:
i've not seen big difference between this method and that of commting.

The obvious difference is that "commenting out" code is an abuse of the
syntax. But perhaps you're not so interested in clarity, and want a more
practical motivation. Okay, here it is:

foo(); /* do the foo thing */
if(condition) /* we only want to bar if there's an 'r' in the month */
{
bar(); /* this will use the default directory, C:\bar\ */
baz(); /* don't forget to baz everything back to normal */
}

Observe the problem with "commenting out" this code:

/*
foo(); /* do the foo thing */
if(condition) /* we only want to bar if there's an 'r' in the month */
{
bar(); /* this will use the default directory, C:\bar\ */
baz(); /* don't forget to baz everything back to normal */
}
*/

See the difficulty? Only the foo() call has been "commented out". And now
you have a syntax error on the last line - "unmatched closing comment" or
similar.

Now let's do it properly:

#if 0
foo(); /* do the foo thing */
if(condition) /* we only want to bar if there's an 'r' in the month */
{
bar(); /* this will use the default directory, C:\bar\ */
baz(); /* don't forget to baz everything back to normal */
}
#endif

No syntax error. No problem with existing comments. And to undo it, you need
only change a single character (change 0 to 1) - and of course it's just as
easy to re-do it.
how to understand this ? i am so interesting

Unmatched closing comment.
 
K

Keith Thompson

Mark McIntyre said:
Well, you could us an cross-ref tool to build up a list of which
functions are used and which #include they come from, then by process
of elimination work out which ones you don't need. If you have a many
MLOC legacy project split into dozens of libs, thats how I'd do it.

The cross-ref tool would only tell you about headers that provide
function declarations.
 
K

Keith Thompson

Richard Heathfield said:
Steven Woody said:

Please, please, please don't do this. If you want to rip them out
temporarily, do it like so:

#if 0
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quux.h"
#endif

Then, as you discover you need them, fish them out of the #if and into the
code proper.

Comment syntax is for adding something extra to the code, not for taking
something away.

Uncomfortable as it is to disagree with Richard, I have to say I don't
think this is a big deal. Commenting out substantial blocks of code
is a bad idea, partly because comments don't nest, but I don't see a
problem with commenting out #include directives one at a time:

/* #include "foo.h" */
/* #include "bar.h" */
/* #include "baz.h" */
/* #include "quux.h" */

With the "#if 0", re-adding "bar.h" results in:

#if 0
#include "foo.h"
#endif
#include "bar.h"
#if 0
#include "baz.h"
#include "quux.h"
#endif

as opposed to:

/* #include "foo.h" */
#include "bar.h"
/* #include "baz.h" */
/* #include "quux.h" */

which makes it much easier to tell at a glance which lines are active
and which ones aren't.

Furthermore, the whole idea any #includes that are commented out will
eventually be removed altogether, so the comments are only temporary.

There is a risk if you have comments on the #include lines, but then
you just have to be careful to comment out only the directive, not the
entire line.
 
R

Richard Heathfield

Keith Thompson said:
Uncomfortable as it is to disagree with Richard,

That should tell you something right there. :)
I have to say I don't
think this is a big deal. Commenting out substantial blocks of code
is a bad idea, partly because comments don't nest, but I don't see a
problem with commenting out #include directives one at a time:

/* #include "foo.h" */
/* #include "bar.h" */
/* #include "baz.h" */
/* #include "quux.h" */

With the "#if 0", re-adding "bar.h" results in:

#if 0
#include "foo.h"
#endif
#include "bar.h"
#if 0
#include "baz.h"
#include "quux.h"
#endif

Huh? What are you talking about?

Before:

#if 0
#include "foo.h"
#include "bar.h"
#include "baz.h"
#include "quux.h"
#endif

Edit:

/bar
dd2jp

After:

#if 0
#include "foo.h"
#include "baz.h"
#include "quux.h"
#endif
#include "bar.h"

The quickest way I can find to remove the comments you used is:

/bar
03x$2Xx

which is actually slightly more work.
 
M

Mark McIntyre

Please, please, please don't do this. If you want to rip them out
temporarily, do it like so:

(example using #if 0)
what advantage does this have over

//#include "foo.h"
//#include "bar.h"
Comment syntax is for adding something extra to the code, not for taking
something away.

Dubious. Commenting out is extremely useful during debugging. When it
comes to prod, he will presumably delete the lines entirely anyway.
Mark McIntyre
 
M

Mark McIntyre

how to understand this ? i am so interesting

Richard means that when your code is production ready, the only
commented areas should be actual comments - there should be no code
blocks commented out.

I almost agree with this. If there were a simple single-line macro way
to hide a line from the compiler, I'd agree entirely. As it is
however, the C++ // comment is very useful for commenting out debug
that you want to retain but not use all the time.
Mark McIntyre
 
M

Mark McIntyre

On Sat, 14 Jan 2006 17:00:43 +0000 (UTC), in comp.lang.c , Richard

(snip example of nested comments)
See the difficulty? Only the foo() call has been "commented out".

You can do anything if you're careless. :)
Commenting out entire code blocks like that is indeed a bad idea.

On the other hand, im my opinion
foo();
//printf("msg I don't need when in prod\n");
bar();

is pretty useful.

Its no big deal though.
Mark McIntyre
 
M

Mark McIntyre

Huh? What are you talking about?

#if 0
#include "foo.h"
#include "baz.h"
#include "quux.h"
#endif
#include "bar.h"

What if bar requires baz but not foo or quux ? More gratuitous entries
in cvs....
which is actually slightly more work.

Feel the power of the dark side, Anakin. The // comment is your ally.
:)

Mark McIntyre
 
M

Mark McIntyre

The cross-ref tool would only tell you about headers that provide
function declarations.

You're right , you'd need to be careful that you understood how the
tool worked. That said, I've used a tool that completely x-ref'ed a
module to the extent of listing all objects and their origins. From
that it would be pretty simple to parse out all unused headers in each
source module.

It'd probably still be quicker to use the comment-out approach tho!



Mark McIntyre
 

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,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top