Frage

Is there any advantage on explicitly prototype local functions in C/C++, instead of defining the functions before use? By local I mean functions only used whithin their source file. An example is this:

#include "header.h"

static float times2(float x){
    return 2*x;
}

static float times6(float x){
    return times2(3*x);
}

int main(void){

    // Other stuff ...

    float y = times6(1);

    // Other stuff ...
}

Versus this:

#include "header.h"

// Local function prototypes
static float times2(float);
static float times6(float);

// Main
int main(void){

    // Other stuff ...

    float y = times6(1);

    // Other stuff ...
}

// Local functions definition
static float times2(float x){
    return 2*x;
}

static float times6(float x){
    return times2(3*x);
}

Personally I prefer to use the first option as there is less code to write and (for me) the file is easier to read, but now I wonder if there is any technical reason to prefer the second option.

EDIT: I added static to times2() and times6(), see @Gangadhar answer and comments following.

War es hilfreich?

Lösung 2

There are cases when you need to declare the function prototype beforehand, i.e. the compiler needs to know a functions prototype before you are able to use that function.

Consider these functions that do nothing particularly useful:

int foo(int x)
{
    if(x < 1) return x;
    else return x + bar(x-1);
}

int bar(int x)
{
    if(x < 3) return x;
    return x * foo(x-1);
}

If you try to compile this, the compiler gets mad at you:

error: 'bar' was not declared in this scope

You need to put the missing prototypes in front of the function using it:

int bar(int);
// as above unchanged

This is the only case where the compiler requires you to put a function prototype before your functions. In all other cases it is perfectly legal to put prototypes anywhere as often as you'd like, so this is also legal:

int foo(int);
int bar(int);
int foo(int);
int bar(int);

Though obviously redundant (please don't do that). Some people consider it good style to put a function prototype of every function within a file at the top of the file, because

  1. you don't have to care about cases in which the compiler requires you to do it anymore, and some people apparently cannot interpret the error message by the compiler (which I think is very concise), and
  2. you see on one view what functions are provided by the file and how they are called.

But this is exactly that, a style discussion. I like to keep my code as short as possible, so I would only use the prototypes that are required by the compiler, but that's purely a matter of taste and convention. When in Rome, do as the Romans or something like that.

Andere Tipps

Aside when needed as a forward reference, the advantage of declaring local (statc) functions is organizational. The same rational applies to static variables.

If a file has dozens of functions (and variables), a preceding local definition helps organization. One may wish to keep such a large collection in an order (A-Z). This order may/may not work well with forward references. By listing all functions/variables (global ones in the (*.h` file) and local ones here (*.c) the organization may be maintained, even though forward reference needs may change during the lifetime of the code.

// function/variable prototypes
static float pi;
static float pi2;
static float times2(float);
static float times3(float);
static float times4(float);
static float times5(float);
static float times6(float);
static float times7(float);
static float times8(float);
static float times9(float);

If prototype is mentiond: the function times2, times6 expects floating point argument to be on the stack or in a register when it is called. If the prototype is omitted, the compiler will have no way of enforcing this and the above mentioned functions will end up operating on some other data on the stack . By including the function prototype, you inform the compiler that the both the functions takes one floating argument and you enable the compiler to catch such kinds of errors.

When a two functions call each other, i.e. FuncA() calling FuncB() and vise versa, then any one of the functions has to declared. This is condition which @M M (above answer) described.

But in any normal situations, declaring function is just a convention, which differ from developer to developer.

Required forward reference and extern are the ONLY reason to use a prototype. Prototypes are noise.Declare the function before you use it. It's cleaner, and only requires you to change the interface once. I don't understand why people use them.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top