2010-06-04 12 views
21

Me pregunto sobre el uso de la palabra clave static como limitante para el alcance variables en un archivo, en C.Razones para utilizar las funciones estáticas y variables en C

La manera estándar para construir un programa en C como veo que es a:

  • tienen un grupo de archivos c que definen funciones y variables, posiblemente alcance limitado con static.
  • tienen un grupo de archivos h que declaran las funciones y posiblemente variables del archivo c correspondiente, para que otros archivos c puedan usar. Las funciones y variables privadas no se publican en el archivo h.
  • cada archivo c se compila por separado en un archivo o.
  • todos los archivos están unidos entre sí en un archivo de aplicación.

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

  • uno es para facilitar la lectura. Informe a los lectores futuros, incluyéndome a mí, que no se accede a una variable en ningún otro archivo.
  • el segundo es evitar que otro archivo c vuelva a definir 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 un archivo redeclar una variable propiedad de otra persona como extern, ¿está bien?)

¿Alguna otra razón?

Igual va para las funciones static. Si el prototipo no se publica en el archivo h, es posible que otros archivos no utilicen la función de todos modos, entonces, ¿por qué definirlo como static? Puedo ver las mismas dos razones, pero no más.

+0

Seis años después, ahora sé que 'estático' no limita el alcance, sino que proporciona un enlace interno. Es similar, si considera una unidad de traducción como un alcance, pero no el término correcto. – Gauthier

Respuesta

23

Cuando hable de informar a otros lectores, considere el compilador como un lector. Si se declara una variable static, que pueden afectar el grado en que optimizaciones patada en.

La redefinición de una variable static como extern es imposible, pero el compilador (como es habitual) le dará suficiente cuerda para sostenerse por sí mismo.

Si escribo static int foo; en un archivo y int foo; en otro, se consideran distintas variables, a pesar de tener el mismo nombre y tipo - el compilador no se quejará pero es probable que llegar a estar muy confundido más tarde tratando de leer y/o depurar el código.(Si escribo extern int foo; en el segundo caso, que se producirá un error al vincular a menos Declaro un no-estática int foo; en otro lugar.)

Las variables globales raramente aparecen en los archivos de cabecera, pero cuando lo hacen, debe ser declarada extern. De lo contrario, según 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, provocará una falla en el enlace (símbolo definido de forma múltiple) y, en el peor, varios casos confusos de eclipsado.

+1

Interesante. Entiendo que este "extern global in header file" todavía necesita definición en un archivo c, ya que extern en el archivo h lo convierte en una mera declaración. – Gauthier

+1

Tiene razón. – crazyscot

7

Al declarar una variable static en el nivel de archivo (static dentro de la función tiene un significado diferente) usted prohíbe que otras unidades accedan a ella, p. si intenta usar la variable dentro de otra unidad (declarada con extern), el vinculador no encontrará este símbolo.

+0

Esta es exactamente una de las dos razones que mencioné: "la segunda es evitar que otro archivo c use el global aparentemente limitado por el alcance redecándolo como 'extern'." ¿Y me pregunté sobre la calidad de tal práctica? – Gauthier

+0

@Gaunthier Entonces su publicación tiene un conflicto interno entonces – qrdl

+2

IMO, 'static' tiene el mismo significado en los tres usos conocidos (variable de archivo, función variable, función) y eso es:" esto tiene un alcance limitado y tiene una constante dirección durante la ejecución del programa ". – Gauthier

1

Si una variable global se declara estática, el compilador a veces puede hacer mejores optimizaciones que si no fuera así. Como 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 generar código más rápido. Muy pocos compiladores/vinculadores pueden hacer este tipo de optimizaciones en diferentes unidades de traducción.

6

Cuando 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 remota". Puede google para más información. This es lo que encontré con una simple búsqueda en Google.

+0

También es interesante, aunque dependiente de la plataforma (mi objetivo tiene solo una instrucción CALL absoluta, y ninguna lejana/cercana). – Gauthier

+0

p. Ej. gcc puede cambiar la convención de llamadas (a algo más rápido) para funciones estáticas en muchas plataformas. – nos

-1

Mi uso favorito de estática es poder almacenar métodos que no tendré que inyectar o crear un objeto para usar, como yo lo veo, los métodos estáticos privados siempre son útiles, donde estática pública hay que poner un poco ¡más tiempo para pensar qué es lo que estás haciendo para evitar lo que Crazyscot definió como, engañarte demasiado y ahorcarte accidentalmente!

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 cosas de forma rápida y eficiente sobre la marcha, ¡no se necesitan objetos!

+2

La pregunta es sobre C, no C++. En C no hay clases, ni métodos, ni miembros privados. Además, en C++ hay una diferencia en funciones estáticas y métodos estáticos. –

+1

¡Uy! Me doy cuenta de que definitivamente leo mal la pregunta. –

0

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

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

Cuestiones relacionadas