开发者

prior declarations of functions

Why do f开发者_如何学运维unctions need to be prior declared in C ?


Functions in modern C language need to be prior-declared for two reasons: 1) to tell the compiler that a specific name is the name of a function (and not of something else), 2) to tell the compiler the exact return type of the function so that the compiler can handle that return correctly.

In C a function can be declared with or without prototype. A prototype declaration provides more information to the compiler. It includes information about the number and the types of function parameters (if any), thus helping the compiler to prepare the arguments for the function call properly.

In C89/90 version of C language the functions didn't have to be prior declared, which resulted in the compiler making assumptions about the function at the point of the call. Needless to say, in many cases this proved to be dangerous.


So that the compiler will be able to detect type errors when you call functions. Of course there are ways around that, but that's the way they chose.


So that the one-pass compiler knows how many bytes to pass for each argument.

Consider:

f(12345);

int f(char input)
{
   printf("%c",input);
}

Without a prototype, the compiler will assume that f accepts ints, and send sizeof(int) bytes to the function (through stack or registers, depending on the platform). But the function will only look at 1 byte, which will give the wrong result.


Because old compilers have limited speed and memory, so they want everything can be done in one pass (just read the file from top to bottom and everything is understood).

Modern-designed compilers can look for functions up, down, even in different files when it is not yet declared at a point.


Basically, you don't....

A lot of compilers will assume you're calling a int Function() signature, if you haven't declared it yet. The linker... hmmm.. will probably not eat that.

The compiler will mind if the signature of the declared Functions doesn't match the calling statement, but it is at a second step where things go wrong: - coding for argument passing and return value pre-code

The latter actually has to be determined for each calling. It's at this second code-generation step that C compiler really misses the declaration (which is what makes a function signature). Then the linker also needs to turn symbolic calls of functions into actual... er... calls. But if the function exists "somewhere" (go investigate the extern modifier), the linker won't be a show stopper.

The exception to all this is the function pointer mechanism, where you tell the compiler and linker the signature to be expected, but the call itself is not decided by the compiler , neither you have a "hardcoded" call by the linker... check it out.


I am sure this is not the only reason, but you can compile files with calls to other functions when you only know the declaration of the function for example from a header file. This is possible without recompiling the definition of the function itself (which might be in another file). But to verify the function is called correctly, the compiler has to know its declaration. Then the linker will take care of the rest.

Here a little example

main.c:

#include "function.h"

int main(){
    function();
    return 0;
}

function.h:

#ifndef FUNCTION_H
#define FUNCTION_H

void function();

#endif

function.c:

#include "function.h"

void function(){}

I am using gcc to compile like that:

gcc function.c -c 

this will produce an object file function.o. Now, when I want to compile my main function, I don't have to compile my function.c file anymore, I only have to know the declaration from the header file and the object file:

gcc main.c function.o -o test

Now, the object file will get linked into my program without recompiling.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜