Re: What's it with this kind of definition?

From: Christian Bau (christian.bau_at_cbau.freeserve.co.uk)
Date: 06/20/04

  • Next message: Charlie Zender: "Reading stdin once confuses second stdin read"
    Date: Sat, 19 Jun 2004 23:40:53 +0100
    
    

    In article <c520b56a.0406191251.5d250ab4@posting.google.com>,
     estudiantin@rediffmail.com (Curious Student) wrote:

    > Some places till now, I've seen function prototypes within functions
    > instead of in the global declaration space, which I thought was the
    > way.
    >
    > I thought it was <I>only</I>:
    >
    > int myfunction(int, int);
    >
    > int main(void)
    > {
    > int a,b;
    > return myfunction(a,b);
    > }
    >
    > But I've also seen:
    >
    > int main(void)
    > {
    > int a, b, myfunction(int, int);
    > return myfunction(a,b);
    > }
    > I've seen this in K&R as well, but haven't come accross a piece that
    > talks about this kinda declaration.
    > What's the deal here? I understand it as follows:
    >
    > It defines the scope of usage. If defined in the global space, much
    > like extern variables, the function can be called from anywhere within
    > the file. If declared within another function, it may be called only
    > from within that function in which it is defined.
    >
    > How true?

    That is probably correct. However, it is an extremely bad programming
    style. Here is why:

    You write functions that are called only from within the file containing
    them (to be more precise: From the same compilation unit), and functions
    that are called from other places as well. For the first type, you
    should use static functions. For the second type, you use extern
    functions.

    Every caller needs to know how to call a function. Since for extern
    functions the caller usually cannot see the definition of the function,
    you write a function declaration and put it into a header file, and
    every caller should include that header file. You might change the
    function parameters at some point in the future; in that case you also
    change the declaration in the header file. If the new declaration is not
    compatible with the old one, then the compiler will refuse to compile
    callers of the function that have not been adapted to the new
    parameters.

    In the example you wrote, the declaration of myfunction is within main.
    If someone changes the definition of myfunction, and also changes the
    declaration in the header file, there is a good chance that the
    declaration in main is missed. I could have changed it to "myfunction
    (double, double, double)", but the compiler would still assume that
    myfunction takes two int arguments, so it will not tell you that the
    call to myfunction is incorrect, and things will go badly wrong.

    You should never have the declaration of a function anywhere but in
    exactly _one_ header file.


  • Next message: Charlie Zender: "Reading stdin once confuses second stdin read"

    Relevant Pages

    • compiling kernel
      ... scripts/kconfig/qconf.h:51: error: `e' was not declared in this scope ... scripts/kconfig/qconf.h:73: error: `int updateList' redeclared as different ... scripts/kconfig/qconf.h:8: error: forward declaration of `class ConfigList' ... ConfigLineEdit' ...
      (alt.os.linux.suse)
    • DBI install problems
      ... before "bool" ... to `int' in declaration of `Perl_Gv_AMupdate' ... definition has no type or storage class ...
      (perl.dbi.users)
    • make Buildworld fails...why?
      ... type defaults to `int' in declaration of `_nc_tracing' ... data definition has no type or storage class ...
      (freebsd-questions)
    • Compilation problem
      ... "PRIntn" ... no type or storage class ... `int' in declaration of `_PR_MD_GETFILEINFO' ...
      (comp.unix.bsd.freebsd.misc)
    • Re: bug in Real-Time Preemption
      ... lib/rwsem.c:153: warning: type defaults to `int' in declaration of `type name' ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)