"Jeff" <ag*******@netcourrier.com> wrote in
news:3f***********************@nan-newsreader-02.noos.net:
Hello everybody,
I have a question concerning function declarations. When exactly do you
have to declare functions if you want to use them? I have two functions
main() and foo(), respectively defined in main.c and foo.c. There is no
declaration of foo() inside main.c, but main() calls foo().
If I compile both files (using gcc's -c option), and then link them,
main() calls foo() without any problem. How come ? Wasn't I suppose to
declare foo() within main.c so main() could call it?
If foo() preceeded main() in the file you got the prototype from the
definition. E.g.
static int foo(void) /* definition and prototype in one */
{
return 0;
}
/* Since foo() is above main(), C already has foo's prototype.
*/
int main(void)
{
return foo();
}
Moreover, what exactly is the use of static functions ?
A simplistic view can be used if not too picky: "static means the static
thing has duration for the life of the program and is restricted in scope
to the nearest enclosing brace or translation unit." My words, not the
spec. So using my smushy definition, you can say that a static function
will exist for the life of the program and be visible (scoped) to only the
file that contains it. Similarly,
int foo(void)
{
static int butter;
return ++butter;
}
int main(void)
{
foo();
return 0;
}
butter will exist for the life of the program and be visible only within
foo() since foo's opening brace the nearest enclosing brace.
Why would you
want to restrict a function to a certain file ?
The question is the otherway round, why make a function visible outside a
module? Answer, because it is absolutlely essential to using the module.
Many functions to work within a module but have not externally usable
benefit.
Try to think about a module and what interfaces into it you feel are the
minimal ones you should provide to consumers of the module and make only
those functions non-static and then prototype them in the module's
accompanying header file.
Example disk.c:
static unsigned char readRegister(int regOffset)
{
unsigned char regValue;
regValue = /* some system specific stuff */;
return regValue;
}
static void writeRegister(unsigned char regValue, int regOffset)
{
/* some system specific stuff */ = regValue;
}
int dsk_readSector(void *pBuf, size_t bufSize, unsigned long sectorLba)
{
writeRegister(sectorLba, LBA_OFFSET);
writeRegister(WRITE_PIO, CMD_OFFSET);
dma_configRead(pBuf, bufSize);
return !(readRegister(STATUS_OFFSET) & ERR);
}
So here I, the consumer disk.c, care only about reading a sector, I don't
care how disk.c does this. I care only about reading. Thus, as the
implementer I hide read/writeRegister() in the file and expose only
dsk_readSector() in disk.h for external consumers. Also, as the
implementer, I keep consumers away from the disk registers by not
publishing a means to screw with them (this is good).
Does this make sense now?
--
- Mark ->
--