static (a nivel de archivo/módulo):
static, el ámbito está limitado al módulo (archivo) en el que se compila.extern:
Importante: static se utiliza para ocultar la implementación, extern para vinculación entre módulos.
Ejemplo:
main.c:
static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }
shared.c:
int shared_var = 10;
Intentar usar hidden_var desde otro archivo generará un error de enlace.
¿Qué sucederá al definir una variable con el mismo nombre y diferentes especificadores static/extern en diferentes módulos?
Respuesta: Cada variable static (por ejemplo, static int foo; en diferentes archivos) es un objeto completamente independiente. La declaración extern int foo; busca una variable global compartida con el nombre foo. No se puede mezclar static y extern; esto dará un error de enlace si en un archivo foo se define como static y en otro se declara extern.
Historia En un proyecto se descubrió la duplicación de funciones con el mismo nombre (sin static) en diferentes módulos: el enlazador solo vinculó una de ellas, la otra "se perdió", lo que afectó la lógica de la aplicación.
Historia En un proyecto grande se declaró una variable global
int counter;en dos módulos, ambas veces sin extern. Como resultado, el comportamiento de la aplicación dependía del orden de enlace, a veces aparecían símbolos en conflicto.
Historia Un módulo utilizó una función con un ámbito erróneo: estaba definida como static, y el desarrollador intentó llamarla desde otro archivo de código; el programa no se compilaba sin cambiar el modificador a extern (o sin eliminar static).