Razones para usar funciones y variables estáticas en C


Me pregunto sobre el uso de la palabra clave static como limitación de alcance para variables en un archivo, en C.

La forma estándar de construir un programa C como yo lo veo es:

  • tiene un montón de archivos c que definen funciones y variables, posiblemente con un alcance limitado con static.
  • tienen un montón de archivos h que declaran las funciones y posiblemente variables del archivo c correspondiente, para que otros archivos c lo usen. Las funciones y variables privadas no se publican en la h file.
  • cada archivo c se compila por separado a un archivo o.
  • todos los archivos o están vinculados a un archivo de aplicación.

Veo dos razones para declarar un gobal como static, si la variable no se publica en el archivo h de todos modos:

  • uno es para la legibilidad. Informar a futuros lectores incluyéndome a mí mismo que no se accede a una variable en ningún otro archivo.
  • el segundo es evitar que otro archivo c vuelva a declarar la variable como extern. Supongo que al enlazador no le gustaría que una variable fuera extern y static. (No me gusta la idea de que un archivo vuelva a declarar una variable propiedad de otra persona como extern, ¿está bien la práctica?)

¿Alguna otra razón?

Lo mismo ocurre con las funciones static. Si el prototipo no está publicado en el archivo h, es posible que otros archivos no usen la función de todos modos, así que ¿por qué definirlo static en absoluto? Puedo ver las mismas dos razones, pero no más.

Author: Gauthier, 2010-06-04

6 answers

Cuando hable de informar a otros lectores, considere al compilador como un lector. Si se declara una variable static, eso puede afectar el grado en que las optimizaciones se activan.

Redefinir una variable static como extern es imposible, pero el compilador (como de costumbre) le dará suficiente cuerda para colgarse.

Si escribo static int foo; en un archivo y int foo; en otro, se consideran variables diferentes, a pesar de tener el mismo nombre y tipo-el compilador no se quejan, pero probablemente se confundirán más tarde tratando de leer y / o depurar el código. (Si escribo extern int foo; en el segundo caso, no se enlazará a menos que declare un int foo; no estático en otro lugar.)

Las variables globales rara vez aparecen en los archivos de cabecera, pero cuando lo hacen deben declararse extern. Si no, dependiendo de su compilador, corre el riesgo de que cada archivo fuente que incluya ese encabezado declare su propia copia de la variable: en el mejor de los casos, esto causará un error de enlace (símbolo de definición múltiple) y en el peor de los casos confusos de eclipsar.

 25
Author: crazyscot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 12:20:23

Al declarar una variable static a nivel de archivo (static dentro de la función tiene un significado diferente) prohibes que otras unidades accedan a ella, por ejemplo, si intentas usar la variable dentro de otra unidad (declarada con extern), el enlazador no encontrará este símbolo.

 8
Author: qrdl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 12:43:51

Cuando se declara una función estática la llamada a la función es una "llamada cercana" y en teoría funciona mejor que una "llamada lejana". Puede buscar más información en Google. Esto es lo que encontré con una simple búsqueda en Google.

 6
Author: INS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 13:07:58

Si una variable global es declarada estática, el compilador a veces puede hacer mejores optimizaciones que si no lo fuera. Debido a que el compilador sabe que no se puede acceder a la variable desde otros archivos fuente, puede hacer mejores deducciones sobre lo que está haciendo su código (como "esta función no modifica esta variable"), lo que a veces puede hacer que genere código más rápido. Muy pocos compiladores / enlazadores pueden hacer este tipo de optimizaciones a través de diferentes unidades de traducción.

 1
Author: Adam Rosenfield,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 12:19:07

Si declara una variable foo en el archivo a.c sin hacerla estática, y una variable foo en el archivo b.c sin hacerla estática, ambas son automáticamente externas, lo que significa que el enlazador puede quejarse si inicializa ambas, y asignar la misma ubicación de memoria si no se queja. Espera diversión depurando tu código.

Si escribes una función foo () en el archivo a.c sin hacerla estática, y una función foo () en el archivo b.c sin hacerla estática, el enlazador puede quejarse, pero si no lo hace, todas las llamadas a foo () llamarán a la misma función. Espera diversión depurando tu código.

 0
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 06:58:23

Mi uso favorito de la estática es ser capaz de almacenar métodos que no tengo que Inyectar o crear un objeto para usar, la forma en que lo veo es, Los métodos estáticos Privados siempre son útiles, donde la estática pública tiene que poner un poco más de tiempo en pensar en lo que está haciendo para evitar lo que se define como locura, conseguir que su auto demasiada cuerda y accidentalmente colgando uno mismo!

Me gusta mantener una carpeta para clases de ayuda para la mayoría de mis proyectos que consisten principalmente en métodos estáticos para hacer las cosas de forma rápida y eficiente sobre la marcha, no se necesitan objetos!

 -1
Author: Jake Kalstad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-04 13:51:48