C extern 关键词分析

C extern 关键词分析

原文链接

作用

首先我们区分两个 术语

  • 声明 (declaration) : 仅表示,存在 变量 / 函数,变量的类型 / 函数的参数和返回值,并不分配内存 / 定义实现
  • 定义 (definition) : 除了 声明 的作用外,还为变量分配内存 / 定义函数实现。
  • 声明定义 的功能子集
  • 声明 可以多次,但 定义 只能一次

所以其作用可以解释为

  • 增加变量 / 函数的可见范围,即,可以使用程序内任一位置定义的变量 / 函数
  • 带有 extern 声明时,编译器认为在程序的某一位置有所定义,因此不会报错,而会使用该声明继续编译

函数

函数的声明 / 定义 默认带有 extern 关键字

 int foo(int arg1, char arg2);
 被编译器视为
 extern int foo(int arg1, char arg2);

编译器认为在程序的某一位置,该函数有所定义,因此不会报错,而会使用该声明继续编译

变量

变量的声明 默认不带有 extern 关键字

  • 区分 声明定义

    // 仅声明
    extern int var;
    // 定义
    int var;
    // 声明必须显式地带上extern关键字,否则会混淆定义和声明,声明时不分配内存
    
  • 代码分析

    • 编译通过,var在全局定义

      int var;
      int main(void) {
        var = 10;
        return 0;
      }
      
    • 编译通过,var在全局声明,虽然没有其他位置定义,但并未使用

      extern int var;
      int main(void) {
      	return 0;
      }
      
    • 编译不通过,var在全局声明,而且试图修改值,但并未定义,故在链接时会报错

      extern int var;
      int main(void) {
        var = 10;
        return 0;
      }
      
    • 如果在其他文件定义var,则上述情况没有问题

      #include "somefile.h"
      // #pragma once
      // int var;
      extern int var;
      int main(void) {
        var = 10;
        return 0;
      }
      

声明时定义,视为定义

以下代码,视为全局定义var (分配内存),因此编译通过

extern int var = 0;
int main(void) {
  var = 10;
  return 0;
}

总结

  • 声明可以多次,定义只有一次
  • extern 声明可以视为,在程序的某一处有定义,并且可以使用,顺利编译;如果没有定义,可能出现链接错误
  • 函数声明默认 extern,变量声明需要显式extern
  • 变量 extern 声明,并初始化时,视为定义
posted @ 2021-05-17 23:39  Jamgun  阅读(54)  评论(0编辑  收藏  举报