La statement estática de m sigue la statement no estática

Estoy probando un pequeño ejemplo para conocer la variable externa estática y sus usos. La variable estática es de scope local y la variable externa es de scope global.

static5.c

#include #include "static5.h" static int m = 25; int main(){ func(10); return 0; } 

static5.h

 #include int func(val){ extern int m; m = m + val; printf("\n value is : %d \n",m); } 

gcc static5.c static5.h

o / p:

 static5.c:3: error: static declaration of m follows non-static declaration static5.h:3: note: previous declaration of m was here 

Editado

El progtwig correcto:

 ac: #include #include "a1_1.h" int main(){ func(20); return 0; } a1.h: static int i = 20; a1_1.h: #include "a1.h" int func(val){ extern int i; i = i + val; printf("\ni : %d \n",i); } 

Esto funciona bien perfectamente bien. Pero esto se comstack en una sola unidad de comstackción. Por lo tanto pude acceder a la variable estática. A través de la unidad de comstackción no podemos usar la variable estática usando la variable externa.

Recuerda esto (citando a Eli Bendersky):

  • Una variable estática dentro de una función mantiene su valor entre invocaciones.
  • Una variable global estática o una función se “ve” solo en el archivo que se declara en

En su código, static int m = 25; significa que el scope de m se limita solo a ese archivo , es decir, solo es visible dentro de static5.c y en ninguna otra parte.

Si desea utilizar m fuera de static5.c asegúrese de eliminar la palabra clave static de la statement de la variable.

Para una explicación más canónica, junto con un ejemplo, vea esta respuesta por Eli Bendersky

EDITAR: (según la recomendación de Klas) ** El scope real es una unidad de comstackción, no el archivo de origen. La unidad de comstackción es la forma en que el archivo se ve después del paso del preprocesador.

static tiene una lógica muy simple. Si una variable es static , significa que es una variable global, pero su scope está limitado a donde está definida (es decir, solo visible allí). Por ejemplo:

  • Fuera de una función: variable global pero visible solo dentro del archivo (en realidad, la unidad de comstackción)
  • Dentro de una función: variable global pero visible solo dentro de la función
  • (C ++) Dentro de una clase: variable global pero visible solo para la clase

Ahora veamos lo que dice la norma C11 con respecto a static y extern (énfasis mío):

6.2.2.3

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

6.2.2.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.

6.2.2.7

Si, dentro de una unidad de traducción, aparece el mismo identificador con enlaces internos y externos, el comportamiento es indefinido.

Así que la norma dice eso primero, si tienes:

 static int m; extern int m; 

entonces la segunda statement (con extern ) consideraría la primera y al final m aún sería static .

Sin embargo, en cualquier otro caso, si hay declaraciones con vínculos internos y externos, el comportamiento no está definido. Esto realmente nos deja con una sola opción:

 extern int m; static int m; 

Es decir, statement extern antes de statement static . gcc fue lo suficientemente bueno como para darte un error en este caso de comportamiento indefinido .

El problema es exactamente como se indica en el mensaje de error. m se declara como int normal pero luego se define como static int .

extern le dice al comstackdor / vinculador que busque la variable en la tabla global de variables.

static (fuera de una función) le dice al comstackdor que excluya la variable de la tabla global de variables.

¿Ves el conflicto?

Para solucionar el problema, elimine la palabra clave static de la definición o mueva la definición sobre la inclusión de static5.h .

Debe tenerse en cuenta que la forma en que ha diseñado sus archivos no se considera la mejor práctica. Los archivos de inclusión no suelen contener funciones.

elimine la palabra clave estática mientras declara my los errores se eliminarán y podrá obtener la respuesta en 50. La palabra clave estática tiene el scope de restringir dentro del archivo.