Static keyword in function declaration can be miss

2019-02-09 04:53发布

问题:

I want to have a static function which I declare in my .c file before defining it:

//file a.c version 1
static int foo();
...
static int foo()
{
...
}

However, it seems that I can leave the static keyword out of the function definition and I get no compiler warnings... e.g.

//file a.c version 2
static int foo();
...
int foo()
{
...
}

Am I correct in assuming these two forms are exactly the same?
If so, why is this discrepancy allowed and which form should I use?

回答1:

Yes 7.1.1/6

A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const.

See also the examples of 7.1.1/7



回答2:

7.1.1/7:

The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope, each declaration declaring the same object name or the same overloading of a function name shall imply the same linkage.

7.1.1/6: (Thanks Steve - this is also needed for the answer to be clear)

A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage.

Yes, those two are the same.

This however is invalid:

int foo();

static int foo() {
  return 0;
}


回答3:

static - in this context - only affects the scope, when you declare a function static it has file scope. So you can easily check if it is the same by trying to access the function from another source.

that way we avoid the discussions about compiler language etc.



回答4:

The static attribute changes the visibility to the compilation unit. This allows to use the same name in different files for different purposes. You should use the static only once. If you have a prototype, you must do here.

When you are asking for C++ you should not use static but anonymous namespace to make the symbold private for the compilation unit:

namespace {
    int foo();
}

void bar()
{
    foo();
}


回答5:

As a sidenote, C++ provides a superior alternative to static. You can also use unnamed namespace here

Example,

namespace 
{  
   void f()
   {
   }
}

See these:

Superiority of unnamed namespace over static?
Why an unnamed namespace is a "superior" alternative to static?