user13744616
user13744616

Reputation:

Using static keyword in definition vs declaration in C

The following compiles fine, using static only during declaration of function:

#include <stdio.h>

static int a();

int a(){
 return 5;
}

int main(){
 printf("%d\n", a());
 return 0;
}

As a side note, same behaviour as above happens with inline functions, i.e only the declaration could have the keyword.

However the following fails, doing the same but on a variable:

#include <stdio.h>

static int a;

int a = 5;

int main(){
 printf("%d\n", a);
 return 0;
}

Getting thew error: non-static declaration of 'a' follows static declaration.

What is with the difference?

Upvotes: 2

Views: 617

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310980

This quote from the C Standard shows the difference )6.2.2 Linkages of identifiers)

5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

So a function looks like it has the implicit storage specifier extern (but it does not mean that it has the external linkage opposite to an object identifier that in this case has the external linkage).

Now according to the following quote

4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage

So the function has the internal linkage due to its initial declaration with the storage specifier static.

As for the identifier of a variable then

7 If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

The resume from the above cited quotes is the following. If a function has no explicitly specified storage class specifier extern then its linkage is determined by a prior function declaration (if such a declaration exists). As for an identifier of object then in this case it has the external linkage. And if there is a prior declaration of the identifier with the internal linkage then the behavior is undefined.

Upvotes: 3

Related Questions