draper@buster.cps.msu.edu (Patrick J Draper) (06/21/91)
I'm interested in what others think of the practice of declaring function prototypes locally within a procedure. local: foo () { int bar (void); int x; x = bar (); } -------------------------------------------------------------------- global: int bar (void); foo () { int x; x = bar (); } The advantage to the local declaration that I can see is that an unintentional call to bar() will be flagged by the compiler. I prefer to use the global declaration because if the definition of bar should change, there's one place to change the prototype. Any other opinions? Thanks, ------------------------------------------------------------------------ Patrick Draper "College is supposed to prepare you for the future, cps.msu.edu but all my future's behind me." draper@cps.msu.edu -- My GrandPa, age 85, Fall 1990 graduate of Western Michigan University ------------------------------------------------------------------------
scs@adam.mit.edu (Steve Summit) (06/21/91)
In article <1991Jun20.202241.7531@msuinfo.cl.msu.edu> draper@buster.cps.msu.edu (Patrick J Draper) writes: >I'm interested in what others think of the practice of declaring >function prototypes locally within a procedure. >The advantage to the local declaration that I can see is that an >unintentional call to bar() will be flagged by the compiler. I prefer to >use the global declaration because if the definition of bar should >change, there's one place to change the prototype. >Any other opinions? Most certainly. If prototypes are used, they MUST be placed in header files (which of course is usually tantamount to "global placement"), and then #included by all source files in which the function(s) is called, AND in the source file where the function is defined. This way, there's *really* only one place to change the prototype, and the compiler can check the prototype against the definition. If a prototype for an external (i.e. defined in another source file) function is placed in a source (non-header) file, it's far too easy to forget to update it if/when the definition changes, and the prototype then does more harm than if it hadn't been used at all (it inserts implicit casts and/or generates warnings based on an obsolete parameter list). (This assumes you're using multiple source files at all, and is written from a C perspective. The use of prototypes is considerably less optional in C++, and recommended practice for prototype placement may be different. My remarks are targeted at comp.lang.c; note that this article, like the one to which it responds, is also crossposted to comp.lang.c++ .) The possibility of an inadvertent call (which might be flagged if local prototypes were routinely used) is comparatively minor (and one I've never worried about; I think that local extern data declarations are a bit silly, too). Steve Summit scs@adam.mit.edu
Dave.Harris@f14.n15.z1.fidonet.org (Dave Harris) (06/22/91)
>The advantage to the local declaration that I can see is that an >unintentional call to bar() will be flagged by the compiler. I prefer to >use the global declaration because if the definition of bar should >change, there's one place to change the prototype. >Any other opinions? Normally that is the best way to do it. In the gutless wonder world of the IBM PC and the crummy compilers such as Microsoft's that run out of memory when you include lots of definitions it can help to just prototype what you need as opposed to including a whole .h file. Helps the compile speed to (and microsoft needs all the help it can get). -- Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!15!14!Dave.Harris Internet: Dave.Harris@f14.n15.z1.fidonet.org
mvm@caesun6.harris-atd.com (Matt Mahoney) (06/24/91)
In article <1991Jun20.202241.7531@msuinfo.cl.msu.edu> draper@buster.cps.msu.edu (Patrick J Draper) writes: >I'm interested in what others think of the practice of declaring >function prototypes locally within a procedure. Functions are always global, so their prototypes should be global too. -------------------------------- Matt Mahoney, mvm@epg.harris.com #include <disclaimer.h>
fxsdb@acad3.alaska.edu (06/25/91)
In article <6592@trantor.harris-atd.com>, mvm@caesun6.harris-atd.com (Matt Mahoney) writes: > In article <1991Jun20.202241.7531@msuinfo.cl.msu.edu> > draper@buster.cps.msu.edu (Patrick J Draper) writes: > >>I'm interested in what others think of the practice of declaring >>function prototypes locally within a procedure. > > Functions are always global, so their prototypes should be global too. > Functions can be declared locally with local prototypes which was, I believe, the focus of the question. I much prefer global functions, as this encourages writing general functions which are reused throughout the code, and can easily be #included. > -------------------------------- > Matt Mahoney, mvm@epg.harris.com > #include <disclaimer.h> -Scott (fxsdb@acad3.alaska.edu)
bhoughto@hopi.intel.com (Blair P. Houghton) (06/25/91)
In article <1991Jun24.132406.1@acad3.alaska.edu> fxsdb@acad3.alaska.edu writes: >In article <6592@trantor.harris-atd.com>, mvm@caesun6.harris-atd.com (Matt Mahoney) writes: >> Functions are always global, so their prototypes should be global too. > >Functions can be declared locally with local prototypes which was, I believe, >the focus of the question. I much prefer global functions, as this encourages >writing general functions which are reused throughout the code, and can easily >be #included. Block-scoped function definitions can import block-scoped variables. Very handy when hacking a decision tree into a former straight-flow construct. --Blair "Information hiding in the rushes."
alanb@sdl.mdcbbs.com (06/25/91)
In article <4845@inews.intel.com>, bhoughto@hopi.intel.com (Blair P. Houghton) writes: > In article <1991Jun24.132406.1@acad3.alaska.edu> fxsdb@acad3.alaska.edu writes: >>In article <6592@trantor.harris-atd.com>, mvm@caesun6.harris-atd.com > (Matt Mahoney) writes: >>> Functions are always global, so their prototypes should be global too. >> >>Functions can be declared locally with local prototypes which was, I believe, >>the focus of the question. I much prefer global functions, as this encourages >>writing general functions which are reused throughout the code, and can easily >>be #included. > > Block-scoped function definitions can import block-scoped > variables. > > Very handy when hacking a decision tree into a former > straight-flow construct. > > --Blair > "Information hiding in the rushes." But block-scoped function definitions (as opposed to declarations) aren't available in C (or C++)? (Thinks - hang on, you're allowed block scope classes with member functions aren't you - checks manual - local classes have function scope, and can import only static variables from the enclosing scope - Ellis & Stroustrup 9.8) Has anyone out there found this useful? Or was this a recommendation to use something other than C/C++ to get nested functions? I agree with the "declare it once only" (in the include file) principle. C++ type-safe linkage does at least give you a chance of catching incorrect local declarations though (unless they're extern "C"). alanb@sdl.mdcbbs.com Alan Braggins `cat ~/.disclaimer`
phil@phd.UUCP (H Phil Duby) (06/25/91)
In article <1991Jun21.004933.4197@athena.mit.edu> scs@adam.mit.edu (Steve Summit) writes: > In article <1991Jun20.202241.7531@msuinfo.cl.msu.edu> draper@buster.cps.msu.edu (Patrick J Draper) writes: > >I'm interested in what others think of the practice of declaring > >function prototypes locally within a procedure. > >The advantage to the local declaration that I can see is that an > >unintentional call to bar() will be flagged by the compiler. I prefer to > >use the global declaration because if the definition of bar should > >change, there's one place to change the prototype. > >Any other opinions? > > Most certainly. If prototypes are used, they MUST be placed in ^^^^ ??? > header files (which of course is usually tantamount to "global > placement"), and then #included by all source files in which the > function(s) is called, AND in the source file where the function > is defined. This way, there's *really* only one place to change > the prototype, and the compiler can check the prototype against > the definition. Another alternative that depends both on the intended usage, and programming style (no flames on that please) coming up :-) If the function you want to prototype (VERY good idea IMHO) is used by a set of other functions that can be convienently grouped together into a single source file, seperate from other functions that should not call the function, declare the prototype global in that source file, but with the static qualifier. Functions in other files will not see the definition, and calls to the function will generate the same errors as if the function was only declared locally. For purists who insist prototypes should also be declared in a header file that is #included by all source files for a program / system (producing global definitions), use the (also talked/beaten to death) option of putting #ifdef #endif pairs around the prototype (with or without the static qualifier), and provide the appropriate define only in the source file(s) that SHOULD be calling the function. This can be both the best and worst option depending on lots of other considerations, mostly to do with personal preferences / in house standards / conventions / practices / size of project / ... I am not promoting any of these as the correct method. Just pointing out another USEABLE alternative that can work in some situations. I don't think we need another flame war. Flames to dev.null, or email if you must. [... normally (IMHO) correct stuff deleted ...] > Steve Summit > scs@adam.mit.edu H. Phil Duby uunet!keyword!calgary!ajfcal!mtroyal!phd!phil (AMiga Users of Calgary) AMUCexpress BBS - 650 meg PD Software Fido net node 1:134/27 (403) 282-5137/5171/5224/5238 3/12/24/24 MNP bps
scs@adam.mit.edu (Steve Summit) (06/26/91)
In article <phil.7968@phd.UUCP> phil@phd.UUCP (H Phil Duby) writes: >In article <1991Jun21.004933.4197@athena.mit.edu> scs@adam.mit.edu (Steve Summit) writes: >> Most certainly. If prototypes are used, they MUST be placed in >> header files... > >If the function you want to prototype (VERY good idea IMHO) is used by a >set of other functions that can be convienently grouped together into a >single source file, seperate from other functions that should not call the >function, declare the prototype global in that source file, but with the >static qualifier. Phil is quite correct. I forgot this exception when I made my blanket statement; a static prototype does belong in the same source file where the function is defined and used. >For purists who insist prototypes should also be declared in a header file... >use the (also talked/beaten to death) option of >putting #ifdef #endif pairs around the prototype (with or without the >static qualifier), and provide the appropriate define only in the source >file(s) that SHOULD be calling the function. I hope Phil didn't get the impression I was that kind of a purist -- blindly putting static prototypes in header files just because of some silly rule would be, well, silly. Using private #ifdefs in public header files is mildly ugly, and should only be resorted to when the private declarations must be shared by a group of "private" files which for some reason cannot be combined into one file, such that the static storage-class cannot be used. (Note, by the way, that a header-file declaration for a static object or function, if such a declaration is used at all, should also have the static storage-class, because the ANSI standard says that the first declaration seen must agree with the definition with respect to the presence or absence of the static storage-class. This is another old and tired topic, which I am not suggesting that we reopen.) Steve Summit scs@adam.mit.edu
mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/28/91)
In article <4845@inews.intel.com>, bhoughto@hopi.intel.com (Blair P. Houghton) writes: > In article <1991Jun24.132406.1@acad3.alaska.edu> fxsdb@acad3.alaska.edu writes: >> In article <6592@trantor.harris-atd.com>, mvm@caesun6.harris-atd.com (Matt Mahoney) writes: >>> Functions are always global, so their prototypes should be global too. >> Functions can be declared locally with local prototypes [...] > Block-scoped function definitions can import block-scoped variables. Are you aware you're cross-posting to comp.lang.c as well as .c++? (Block-scoped functions don't exist in C.) der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu