简体   繁体   中英

If function declaration is not in header file, is static keyword necessary?

If a function declaration isn't in a header file (.h), but is instead only in a source file (.c), why would you need to use the static keyword? Surely, if you only declare it in a .c file, it isn't seen by other files, as you're not supposed to #include .c files, right?

I have already read quite a few questions and answers about this (eg. here and here ), but can't quite get my head around it.

What static does is make it impossible to declare and call a function in other modules, whether through a header file or not.

Recall that header file inclusion in C is just textual substitution:

// bar.c
#include "header.h"

int bar()
{
    return foo() + foo();
}

// header.h
int foo(void);

gets preprocessed to become

int foo(void);

int bar()
{
    return foo() + foo();
}

In fact, you can do away with header.h and just write bar.c this way in the first place. Similarly, the definition for foo does not need to include the header in either case; including it just adds a check that the definition and declaration for foo are consistent.

But if you were to change the implementation of foo to

static int foo()
{
    // whatever
    return 42;
}

then the declaration of foo would cease to work, in modules and in header files (since header files just get substituted into modules). Or actually, the declaration still "works", but it stops referring to your foo function and the linker will complain about that when you try to call foo .

The main reason to use static is to prevent linker clashes: even if foo and bar were in the same module and nothing outside the module called foo , if it weren't static , it would still clash with any other non- static function called foo . The second reason is optimization: when a function is static , the compiler knows exactly which parts of the program call it and with what arguments, so it can perform constant-folding, dead code elimination and/or inlining.

The static keyword reduces the visibility of a function to the file scope. That means that you can't locally declare the function in other units and use it since the linker does not add it to the global symbol table. This also means that you can use the name in other units too (you may have a static void testOutput(); in every file, that is not possible if the static is omitted.)

As a rule of thumb you should keep the visibility of symbols as limited es possible. So if you do not need the routine outside (and it is not part of some interface) then keep it static .

  1. It allows you to have functions with identical names in different source files, since the compiler adds an implicit prefix to the name of every static function (based on the name of the file in which the function is located), thus preventing multiple-definition linkage errors.

  2. It helps whoever maintains the code to know that the function is not exposed as part of the interface, and is used only internally within the file (a non-static function can be used in other source files even if it's not declared in any header file, using the extern keyword).

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