Does anyone have any opinions on not using prototypes unless necessary for functions declared "static". Do you always put them at the top of your translation unit? I tend to but recently I've been thinking about why not rely on the ordering of the functions and in way you can limit some scope of where the function can be called from, potentially forcing yourself to think a little bit more about the scope of the function. I'm still on the side of doing the prototype, but I can see arguments aren't completely baseless for the other side of the fence. I suppose this argument could also be continued on to #define and file scope variables.
I tend to write functions in Pascal order (i.e., define before use) rather than declaring with prototypes. Especially during development when signatures change frequently, having to maintain two copies of the same information is irritating and potentially flow-breaking.
You have to have a prototype visible at the point of use in C++, but not necessarily in C. I prefer to always prototype functions anyway in C. There's no good reason not to. A prototyped function definition is sufficient (again, no such thing as an unprototyped function definition in C++) and I don't see anything wrong with having the function defined as close to its point of use as possible (i.e. just above its first use) and relying on this for the prototype.
On the other hand it can be useful to have a set of function declarations to refer to at one point in a file, but even as someone who doesn't use an IDE that automatically indexes function in source that often, it isn't a big issue for me.
I generally follow the "don't repeat yourself" school of thought and declare static functions at the top of the translation unit. I dislike having too many points of edit when I change a function signature.
Reducing the scope of where the function is visible from seems like a secondary consideration to me - if this was particularly important (e.g. if I wanted to ensure people didn't 'abuse' the function) then I'd consider moving it to another translation unit along with the calling code.
If you do not write prototype declarations for your static functions, then you have to define them before using them. This is a constraint and, as far as I can tell from my own experience, this is a good constraint: it forces the developer to write code in a logical order, and related functions tend to remain grouped together. With declared prototype on top of the file, the code has more potential to become a tangled mess.
Moreover, the not-pre-declaring rule means that when you must add a prototype (because you have a multi-level recursion) then the prototype tends to stick out as a good marker for a difficult piece of code (i.e. the multi-level recursion).
I follow the "define before use" rule myself wherever possible (thus my files always read from the bottom up). That way I don't have to worry about keeping declarations and definitions in sync, at least within the same file.
To be pedantic, you're talking about declarations, not prototypes; prototype refers to the syntax of a declaration/definition (i.e., declaring the number and types of parameters in the parameter list). To be clear, the following declaration and definition use prototype syntax:
/**
* prototype declaration; the number and types of parameters are
* part of the declaration, so the compiler can do type checking
* on the function call
*/
double f(int x, int y, double z);
/**
* prototype definition
*/
double f(int x, int y, double z)
{
...
}
whereas the following declaration and definition do not use prototype syntax:
/**
* non-prototype declaration; the number and types of parameters
* are not specified, so the compiler can't do any type checking
* on the function call.
*/
double f();
...
/**
* non-prototype definition; this is still legal AFAIK, but
* *very* outdated, and should no longer be used
*/
double f(x, y, z)
int x;
int y;
double z;
{
...
}
Whether you define functions before use, or just declare before use and define later, always use prototype syntax.
I like to define my functions by alphabetical order, which helps in finding functions.
A function declaration section at the beginning of the source allows the function definitions to be in any order. I also alphabetize the the declaration section.
Note: This answer applies to C++
It seems to me that you believe that using prototypes is considered good practice and not using them some sort of neglect. I remember that my first C++ docent also attached importance to creating prototypes.
However, in the professional world I have never encountered such a rule. Except for the guideline that you should avoid writing the function/method definitions in the header files. But that's mostly to have a clear separation between interface and implementation and also to avoid potential linker errors.
To answer your question: if a function is only needed within a CPP file then it should be static or be in a namespace to avoid conflicts with externals and it doesn't need to have a prototype.