外部,内部和没有联系或为什么这不起作用?

use*_*756 18 c linkage language-lawyer

根据C标准:

在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明 表示相同的对象或功能.在一个翻译单元内,具有内部链接的标识符的每个声明 表示相同的对象或功能.没有链接的标识符的每个声明 表示唯一的实体.

在我的例子中,我们有三个单独的声明,每个标识符具有不同的链接.所以为什么这不起作用?

static int a; //a_Internal

int main(void) {
    int a; //a_Local
    {
        extern int a; //a_External
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

在函数'main'中:第9行:错误:变量先前声明'static'relayclared'extern'

为什么编译器坚持要重新声明我而不是尝试访问另一个文件中的外部对象?

有效的C++示例供参考:

static void f();
static int i = 0;               // #1
void g() {
  extern void f();              // internal linkage
  int i;                        // #2 i has no linkage
  {
    extern void f();            // internal linkage
    extern int i;               // #3 external linkage
  }
}
Run Code Online (Sandbox Code Playgroud)

Clang和VC似乎都适用于我的C示例; 只有某些版本的GCC(并非所有版本)都会产生上述错误.

usr*_*usr 16

§6.2.2,7说:

如果在翻译单元内,同一标识符同时出现内部和外部链接,则行为未定义.

所以,你的程序有不确定的行为.

§6.2.2,4表示

extern int a; //a_External
Run Code Online (Sandbox Code Playgroud)

有外部链接,因为事先声明的范围内可见int a; //a_Local任何联系.但

static int a; //a_Internal
Run Code Online (Sandbox Code Playgroud)

声明a与内部联系.因此,根据§6.2.2,7 未定义.

  • @ user6898756理由:禁止无法理解的奇怪和深奥规则的结果,没有明显的好处?可能呢?另外,也许,更好的机会来构建正确的编译器和链接器. (2认同)