static(文件/模块级别):
static 的变量和函数,作用域仅限于编译模块(文件)。extern:
重要: static 用于隐藏实现,extern 用于模块之间的链接。
示例:
main.c:
static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }
shared.c:
int shared_var = 10;
尝试从另一个文件访问 hidden_var 将导致链接错误。
如果在不同模块中定义具有相同名称和不同修饰符 static/extern 的变量,会发生什么?
答案: 每个 static 变量(例如在不同文件中 static int foo;)都是完全独立的对象。声明 extern int foo; 会查找一个共享的全局变量 foo。不能混合使用 static 和 extern——这将导致链接错误,如果在一个文件中 foo 被定义为 static,而在另一个文件中被声明为 extern。
故事 在项目中发现了不同模块中同名函数的重复(没有使用 static):链接器只链接了其中一个,另一个“丢失”了,影响了应用程序的逻辑。
故事 在一个大型项目中,在两个模块中声明了全局变量
int counter;,两次都没有使用 extern。结果,应用程序的行为依赖于链接顺序,有时会出现符号冲突。
故事 模块使用了作用域错误的函数:该函数被定义为 static,并且开发者试图从另一个源文件调用它——程序在不更改修饰符为 extern(或删除 static)时无法编译。