Responding to Leschov...
Here's an artificial example:
// isr.c file
...
static void interrupt isr(void)
{
unsigned char i, temp;
#include "usart.c" // serial channel
#include "i2c.c" // I2C channel
...
// modbus.c file
if(RCIF)
{
RCIF=0;
temp = RCREG; // receive data byte
...
// i2c.c file
if(SSPIF)
{
SSPIF = 0;
...
There three separate issues here...
Localization of scope of the includes (i.e., including them in the body
of the .c code). There is no real gain to this because the compiler is
going to include the code statically whether the local block is actually
invoked at run time or not. In fact, it can lead to object bloat if the
same includes are inserted in different places. Since the actual
included code is only visible during run-time debugging or in an
Assembly listing, it really doesn't matter where one includes the file
with respect to readability of the host .c file. So the only
justification is...
Providing code fragments of executable statements (i.e., rather than
modular code blocks). Essentially one is using the compiler's lexical
replacement to insert executable statements without block structuring.
Circumventing the 3GL block structuring should be a warning flag in
itself. There is really no need for this because C already has a macro
facility that could easily have handled the examples. If the code to be
inserted is too large, then it should have been in a procedure to
promote modularity. If one wants to make decisions that are based on
local context, one can use C's #define in a conventional header.
[Being able to change the #define value *within* the .c file body is one
justification for localizing includes. But one doesn't need to include
the C statements to do that; just the #define definition. However, this
is not very robust for maintenance; changing #define values "on the fly"
is much like an assigned goto in FORTRAN. It modifies flow of control in
a way that is not visible to the reader of the .c body. So I would look
for ways to define the decisions in a more visible fashion (e.g.,
additional #defines to capture the particular context).]
Including a .c file rather than a .h file. Given that one is going to do
the second thing, it is probably a good idea to call attention to the
fact that one is not using the C language in a normal way. Using a .c
should raise a flag to the reader that something strange is going on.
Bottom line: IMO such a practice is just getting "cute" with lexical
replacement and should be avoided. Using a language feature in an
unusual way when there are existing language features one could use in a
normal fashion to do the same thing is usually not a good idea. It
increases the risk that a maintainer will be confused and insert defects
when making changes.
--
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
(e-mail address removed)
Pathfinder Solutions
http://www.pathfindermda.com
blog:
http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
(e-mail address removed) for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH