简体   繁体   中英

How important is function declaration?

When I go through books and websites, it is written that function declaration/prototype is a must, but when I run my program without declaring it, it also gives me the right results.

Can you explain why?

(I'm talking about cases where the definition of the function is not before the function that calls it, so the function definition can't provide information about the prototype. If this is not the case, then declaring the function is not obligatory, but it's still considered good practice, since it doesn't rely on the order of function definitions, and it's less error prone when one changes that order.)

Function declarations are important because a calling convention (part of the ABI of a platform) can define different places for arguments and return values based on the types a function returns and accepts as arguments. For example, the return value of a function returning a (large enough) structure is typically placed on the stack, whereas functions returning int usually use a CPU register for the return value. Without function prototoypes, most compilers assume that functions return int , and this can be erroneous. Consider the following example:

// in a separate implementation file
struct foo {
    long long bar;
    char buf[128];
};

struct foo function()
{
    struct foo f = { 0 };
    return f;
}

// in another file - the implementation is invisible here,
// and in the lack of a prototype, the compiler assumes an integer return value
int x = function();

Now this can potentially mess up the stack, because the function pushes the return value on the stack, but the assignment doesn't pop it, since it assumes an integer return value.

In part, it depends on which standard your code is conforming to. The pre-standard compilers were very lax because they did not support prototypes at all. The C89 standard introduced prototypes, but had to allow the vast body of code that already existed to compile. So, prototypes were optional (except, technically, for functions such as printf() that support variable numbers of arguments; for those, a prototype was mandatory in C89, even though compilers did not usually complain — or cause trouble — if the declarations were missing).

With C99 (and C2011), you are supposed to have a prototype declaration of each function visible before a function is used. It is a good idea to have a prototype declaration of each non-static function visible before it is defined. That declaration should be in a header which other files that use the function can include. The header acts as 'referee'; it ensures that the code using the function has the correct declaration information, and that the code defining the function matches the declaration everything else is using.

Generally, unless you push the compiler into a strict mode, it will endeavour to accept programs. Adding options such as -std=c99 -pedantic -Wall -Wextra to GCC will enable a lot of warnings. It is worth having your code compile cleanly under those options.

If you use GCC, you can add warning still more options to ensure you're notified of omissions. Depending on the version of GCC, you can use:

  • -Wmissing-prototypes (warns you if there is no prototype)
  • -Wstrict-prototypes (warns you about non-prototypes, such as extern int func(); )
  • -Wold-style-declaration (warns you about 'old style', K&R, non-prototype declarations)
  • -Wold-style-definition (warns you about 'old style', K&R, non-prototype definitions)

I've been using the first two for ages; all the GCC 4.x and even the 3.x series compilers support them. The latter two I only came across in the last year or so; GCC 4.7.x supports them, but GCC 4.1.x does not (4.5.1 supports them; that's the oldest version other than 4.1.2 I have on hand).

GCC 4.7.x has the useful option: gcc --help=warnings . This gives a list of all the warnings that it supports, with simple summaries:

...
-Wmissing-prototypes        Warn about global functions without prototypes
...
-Wold-style-declaration     Warn for obsolescent usage in a declaration
-Wold-style-definition      Warn if an old-style parameter definition is used
...
-Wstrict-prototypes         Warn about unprototyped function declarations
...

Using function declaration / prototype is a very good practice / design (When you do not need to).

In a lot of case you do not have the choice, or the code will be very hard to maintained.

  • With a program with only one .c file, if you do not use prototype, you must order the function in the right order into the .c file

    => prototype of a function must be declared when you use a function in code before its description.

  • When you will need to write bigger program, you will break your code into separate module. Each module will have 'public' and 'private' function. The later will be declared static (you still need to add prototype at the top of the .c file), and the 'public' function prototype will be into a .h file (header)

As long as the function implementation is located before the function call(s), the code will work without seperate function declaration, because the function has been declared by the implementation itself. Generally - especially for largre programs - you should make a declaration for any function.

仅当在函数描述之前在代码中使用该函数时,才必须声明该函数的原型。

Function declaration is useful to let the compiler detect data type issues as soon as possible. If you create a function requiring a float and instead of that you pass a char it may still work in some cases (for example for a comparison) and broke when you start building code on top of it. In the end the computer represent everything as a bit array, so you can "sum" two characters or concatenate two integers containing a \\0 as if they were strings, but it will make the program a mess to maintain and debug in the future.

Function declaration(also called forward declaration) is required as the compilation of a program is done from top to bottom(ie 1st line to last line)..

It is only required when the function call is before the function implementation..

It is a good practice to mention the compiler that the function declared here is been used somewhere in the program..

Declarations can also be done in a user defined header file..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM