Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

c - Rationale of static declaration followed by non-static declaration allowed but not vice versa

This code will compile and is well defined under current C standards:

static int foo(int);
extern int foo(int);

The standard specifies that in this situation (C11: 6.2.2 Linkages of identifiers (p4)):

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. [...]

... which means that the int foo(int) function is declared static int foo(int).

Swapping these declarations around like this:

extern int foo(int);
static int foo(int);

...gives me a compiler error using GNU GCC:

static declaration of 'foo' follows non-static declaration

My question is: What is the design rationale behind the second case being an error and not handled in a similar way as the first case? I suspect it has something to do with the fact that separate translation units are easier to manage and #include? I feel as though without understanding this, I can open myself up to some mistakes in future C projects.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think the idea of this confusing specification is that an extern declaration can be used inside a function to refer to a global function or object, e.g to disambiguate it from another identifier with the same name

static double a; // a declaration and definition

void func(void) {
  unsigned a;
  .....
  if (something) {
     extern double a; // refers to the file scope object

  }
}

Whereas if you use static you declare something new:

extern double a;  // just a declaration, not a definition
                  // may reside elsewhere
void func(void) {
  unsigned a;
  .....
  if (something) {
     static double a; // declares and defines a new object

  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...