允许使用静态声明和非静态声明的基本原理,反之亦然 [英] Rationale of static declaration followed by non-static declaration allowed but not vice versa

查看:174
本文介绍了允许使用静态声明和非静态声明的基本原理,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码将编译并在当前的C标准下得到很好的定义:

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

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

标准指定在这种情况下( C11:6.2.2标识符链接(p4 )):

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


对于在
a范围内使用存储类说明符extern声明的标识符该标识符的声明是可见的, 31)
如果先前的声明指定了内部或外部链接,则后面的声明中标识符的
链接与$ b相同$ b链接在先前的声明中指定。 [...]

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

...这意味着 int foo(int)函数声明为 static int foo(int)

... 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);

...使用GNU GCC给我一个编译器错误:

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


'foo'的静态声明遵循非静态声明

static declaration of 'foo' follows non-static declaration

我的问题是:第二种情况是错误且未按与第一种情况相似的方式处理的设计原理是什么?我怀疑这与以下事实有关:单独的翻译单元更易于管理,并且 #include ?我感觉好像不了解这一点,就可能在将来的C项目中遇到一些错误。

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.

推荐答案

我认为令人困惑的规范的含义是,可以在函数内部使用 extern 声明来引用全局函数或对象,例如,将其与具有相同名称的另一个标识符区分开来

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

  }
}

这篇关于允许使用静态声明和非静态声明的基本原理,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆