¿De qué sirve declarar una variable estática como extern dentro de una función?

#include  static i = 5; int main() { extern int i; printf("%d\n",i); return 0; } 

¿Alguien puede dar algún caso de uso para declarar una variable estática como externa dentro de un bloque de funciones?

NUEVO: ¿Por qué esto no está permitido?

 int main() { static i = 5; extern int i; printf("%d\n",i); return 0; } 

esto es útil cuando necesita acceder a una variable que reside dentro de otra unidad de traducción, sin exponer la variable externa globalmente (por algunas razones, como la colisión de nombres, o que no se deba acceder directamente a la variable, por lo que se utilizó static para limita su scope, pero el encabezado de esa unidad aún necesita acceso).

Como ejemplo, digamos que tenemos una unidad de traducción foo.c , que contiene:

 //foo.c static int i = 0; 

no debería ser cambiado o accedido directamente fuera de foo.c , sin embargo, foo.h requiere un acceso a i para una función en línea, pero no debería estar expuesto a ninguna unidad de traducción usando foo.h , por lo que podemos usar extern a nivel funcional, para exponerlo solo durante el scope de IncI , la función en línea que requiere el uso de i :

 //foo.h inline void IncI(int val) { extern int i; i += val; } 

Su segundo ejemplo es “no permitido” porque el comstackdor cree que está intentando vincular dos variables diferentes al mismo nombre de símbolo, es decir: crea la static i en el ámbito local, pero busca el extern int i en el ámbito global, pero no lo hace t encontrarlo, porque static i como en el scope de la función. un comstackdor más inteligente simplemente arreglaría el vínculo con la static i , ya sea que esto cumpla o no los estándares, no lo sabría.


Ahora que tengo un documento de estándares de C para trabajar (vergüenza de mí, lo sé …), podemos ver cuál es la postura oficial (en C99):

6.2.2 Enlaces de identificadores

Seccion 3:

Si la statement de un identificador de scope de archivo para un objeto o una función contiene el especificador storageclass static, el identificador tiene un enlace interno.

Sección 4:

Para un identificador declarado con el especificador de la clase de almacenamiento extern en un ámbito en el que una statement previa de ese identificador es visible, si la statement anterior especifica un enlace interno o externo, el enlace del identificador en la statement posterior es el mismo que el enlace especificado en la statement previa. Si no hay una statement previa visible, o si la statement anterior no especifica ningún enlace, entonces el identificador tiene un enlace externo.

por lo tanto, debido a que la static causará un enlace interno, el extern traerá ese enlace al scope actual. También hay una nota al pie que indica que esto puede causar ocultación de variables:

23) Como se especifica en 6.2.1, la statement posterior puede ocultar la statement anterior.

En su segundo caso, le está diciendo al comstackdor que tiene una variable estática (local) i y otra variable (global) i que está definida en otro lugar.