¿Son malas las variables globales? [cerrado]

247

En C / C ++, ¿las variables globales son tan malas como mi profesor cree que son?

GEOCHET
fuente
17
Morderé en caso de que esté tratando de contar una broma ... "¿qué tan malos son?"
Zach Scrivena
13
¡Creo que esta pregunta fue bastante interesante! El desarrollo de software aún enfrenta los mismos escollos desde el principio y los programadores a menudo aún no saben que usar variables globales, gotos, variables con nombre corto NO ES el problema. El código incorrecto se escribe todos los días sin usarlos. +1
Sylvain Rodrigue
69
¿Cómo podemos responder? No nos ha dicho lo mal que su profesor piensa que son. :)
Steve Fallows
99
@Juan Mendes ¡Estoy 100% de acuerdo contigo! El problema del que hablaba es que muchos desarrolladores saben que no deberían usar variables globales, ¡pero simplemente NO saben por qué! Y por lo tanto, he visto muchos softwares grandes donde todas y cada una de las funciones recibieron la misma megaestructura que contiene +100 campos. ¡Miren, no hay variables globales! El mismo problema que las llamadas "buenas prácticas": son buenas prácticas en ALGUNOS contextos, no en todos los contextos. Usarlos PUEDE crear un código ininteligible. Salud.
Sylvain Rodrigue
3
Hay muy pocos buenos usos para las variables globales. Un uso posible, pero discutible, sería un objeto de "configuración" global, que se lee en un archivo de configuración una vez al inicio.
Siler

Respuestas:

257

El problema con las variables globales es que, dado que cada función tiene acceso a ellas, se hace cada vez más difícil determinar qué funciones realmente leen y escriben estas variables.

Para comprender cómo funciona la aplicación, debe tener en cuenta cada función que modifica el estado global. Eso se puede hacer, pero a medida que la aplicación crezca se volverá más difícil hasta el punto de ser prácticamente imposible (o al menos una completa pérdida de tiempo).

Si no confía en variables globales, puede pasar el estado entre diferentes funciones según sea necesario. De esa manera, tendrá una mejor oportunidad de comprender lo que hace cada función, ya que no necesita tener en cuenta el estado global.

Brian Rasmussen
fuente
10
Esta respuesta es realmente buena. Combine esto con la respuesta 'minimizar alcance variable' stackoverflow.com/questions/357187/…
bobobobo
17
Sustituya 'clase' por 'aplicación' y 'estado de objeto' por 'estado global' y cree exactamente el mismo argumento para no usar variables miembro (también conocido como campos) en las clases. La verdadera respuesta es usarlos cuando sea apropiado.
Ian Goldby el
2
Pocas (tal vez tontas) preguntas: 1) Si desea saber qué funciones leen y escriben estas variables, ¿no podría simplemente usar la función "buscar" en un editor para detectar los casos en los que se modifican los valores de estas variables? 2) "Eso se puede hacer ... una completa pérdida de tiempo". ¿Puede dar un ejemplo? 3) "Si no confía en las variables globales, ... no necesita tener en cuenta el estado global". No entiendo cómo eso es una ventaja. Quizás un ejemplo de eso funcione para mí.
Andrei
2
@bobobobo enlace roto, ¿podemos obtener una captura de pantalla de usted, un usuario de 10k +?
noɥʇʎԀʎzɐɹƆ
3
@ noɥʇʎԀʎzɐɹƆ Aquí tienes! i.imgur.com/RwRgJLZ.jpg
Mateen Ulhaq
85

Lo importante es recordar el objetivo general: claridad

La regla "no hay variables globales" está ahí porque la mayoría de las veces, las variables globales hacen que el significado del código sea menos claro.

Sin embargo, como muchas reglas, las personas recuerdan la regla y no lo que la regla pretendía hacer.

He visto programas que parecen duplicar el tamaño del código al pasar una enorme cantidad de parámetros simplemente para evitar el mal de las variables globales. Al final, el uso de globals habría hecho que el programa fuera más claro para quienes lo leen. Al adherirse sin pensar a la palabra de la regla, el programador original había fallado la intención de la regla.

Entonces, sí, los globales son a menudo malos. Pero si siente que al final, la intención del programador se aclara con el uso de variables globales, entonces continúe. Sin embargo, recuerde la caída en la claridad que se produce automáticamente cuando obliga a alguien a acceder a una segunda pieza de código (los globales) para comprender cómo funciona la primera pieza.

Tom West
fuente
8
Sugerir una variable global en lugar de pasar es una receta para hacer que su código no sea reutilizable e inseguro para subprocesos múltiples
Juan Mendes
16
Sugerir globales en las circunstancias correctas es una receta para un código más claro y de mayor rendimiento. "Pasar" requiere una asignación de memoria dinámica de pila constante, y esto sería una tontería para algo que debería ser global, como un búfer global para datos de socket entrantes. Por ejemplo, si tiene una función que lee Winsock recv (), ¿por qué constantemente crea y desasigna este búfer dentro de cada llamada? Haga que el búfer sea global. Varios hilos no lo leerán de todos modos.
James
Curiosamente, ¿qué programa duplica el tamaño del código al pasar parámetros para evitar variables globales? En mi experiencia, el uso de variables globales puede resolver problemas de exposición de datos, pero generalmente hay una lógica compleja adicional que debe agregar para asegurarse de que estas variables mágicas se comporten correctamente.
user2167582
3
Si alguien pasa alrededor de 100 variables, entonces no ha aprendido qué es un objeto. Usar la referencia a este objeto es, en el peor de los casos, pasar un puntero. Diría que la regla no es solo la claridad, sino también la capacidad de prueba, y el uso de un sistema no global tiende a hacer que las cosas sean mucho más fáciles de probar.
UKMonkey
2
"Si alguien pasa alrededor de 100 variables, entonces no ha aprendido qué es un objeto". De acuerdo, pero no todo el mundo está orientado a objetos. Mi ejemplo personal de duplicar el tamaño del código fue un gran programa Fortran, alrededor de 1986. Como recién salido de la universidad, lo "mejoré", agregando unos 30 parámetros a cada llamada, eliminando todos los globales. Luego deshice mi mejora cuando me di cuenta de lo que había forjado.
Tom West
64

Mi profesor solía decir algo como: usar variables globales está bien si las usas correctamente. No creo que alguna vez haya sido bueno usándolos correctamente, así que rara vez los usé en absoluto.

barneytron
fuente
25
Tan verdadero. Son como gotos, si no sabes cuándo usarlos, nunca lo hagas.
David Holm
55
En mi empresa actual, usan staticmuchas variables globales, el lenguaje es C. Al estar confinados a unidades de traducción relativamente pequeñas, comienzan a parecerse a las variables de clase de los objetos C ++.
Vorac
1
Las variables estáticas de @Vorac no son variables globales, son variables locales. Una variable global es una variable disponible en todas partes del programa (por lo tanto, "global", duh). No debe confundirse con las variables de alcance del archivo , que son variables declaradas fuera de cualquier función. Una variable de alcance de archivo estático no es una variable global.
Lundin
1
Para corregir yo mismo, program lifetime, file scope variables. Y se vuelven bastante globales una vez que pasa un puntero a la variable al mundo exterior (lo cual es imposible con las variables automáticas) ..
Vorac
@Lundin Estoy de acuerdo, las staticvariables globales tienen un alcance limitado para la misma unidad de traducción. Pero tienen una vida útil hasta el final del programa como cualquier variable global.
akhilesh1988 12/12/2016
38

Las variables globales solo deben usarse cuando no tienes alternativa. Y sí, eso incluye Singletons. El 90% del tiempo, se introducen variables globales para ahorrar el costo de pasar un parámetro. Y luego ocurre la codificación de subprocesos múltiples / pruebas unitarias / mantenimiento, y tiene un problema.

Entonces sí, en el 90% de las situaciones las variables globales son malas. Es probable que no veas las excepciones en tus años universitarios. Una excepción que puedo pensar fuera de mi cabeza es tratar con objetos inherentemente globales, como tablas de interrupción. Cosas como la conexión DB parece ser global, pero no lo es.


fuente
2
La única excepción que he visto en mi años de la universidad era funciones de gráficos de devolución de llamada. En XWindows, las devoluciones de llamada del mouse no tenían argumentos de datos nulos * que le permitían pasar fragmentos arbitrarios del estado del programa ... (no es que eso sea MUCHO mejor que un global de todos modos ...)
Brian Postow
10
+1 para "Cosas como la conexión DB parece ser global, pero no lo es".
R .. GitHub DEJA DE AYUDAR A ICE
1
Las tablas de interrupción no son globales, hay una por procesador, pero también hay una instancia de su programa por procesador, por lo que se "cancela".
user253751
1
¿Alguien puede aclararme por qué las conexiones de base de datos no son globales (y cuál sería una buena alternativa)? Siempre pensé en las conexiones como uno de los raros casos en que los globales eran aceptables.
Floella
33

El problema que crean las variables globales para el programador es que expande la superficie de acoplamiento entre componentes entre los diversos componentes que utilizan las variables globales. Lo que esto significa es que a medida que aumenta el número de componentes que utilizan una variable global, la complejidad de las interacciones también puede aumentar. Este aumento del acoplamiento generalmente hace que los defectos sean más fáciles de inyectar en el sistema cuando se realizan cambios y también hace que los defectos sean más difíciles de diagnosticar y corregir. Este aumento de acoplamiento también puede reducir el número de opciones disponibles al hacer cambios y puede aumentar el esfuerzo requerido para los cambios, ya que a menudo se debe rastrear a través de los diversos módulos que también usan la variable global para determinar las consecuencias de los cambios.

El propósito de la encapsulación , que es básicamente lo opuesto al uso de variables globales, es disminuir el acoplamiento para hacer que la comprensión y el cambio de la fuente sean más fáciles y seguros y se prueben más fácilmente. Es mucho más fácil usar pruebas unitarias cuando no se usan variables globales.

Por ejemplo, si tiene una variable entera global simple que se está utilizando como un indicador enumerado que varios componentes usan como máquina de estado y luego realiza un cambio agregando un nuevo estado para un nuevo componente, debe rastrear todos los demás componentes para garantizar que el cambio no los afecte. Un ejemplo de un posible problema sería si una switchdeclaración para probar el valor de la variable global de enumeración con casedeclaraciones para cada uno de los valores actuales se está utilizando en varios lugares y sucede que algunas de las switchdeclaraciones no tienen un defaultcaso para manejar un valor inesperado para el global de repente tiene un comportamiento indefinido en lo que respecta a la aplicación.

Por otro lado, el uso de un área de datos compartidos podría usarse para contener un conjunto de parámetros globales a los que se hace referencia en toda la aplicación. Este enfoque a menudo se usa con aplicaciones integradas con pequeñas huellas de memoria.

Cuando se usan variables globales en este tipo de aplicaciones, normalmente la responsabilidad de escribir en el área de datos se asigna a un solo componente y todos los demás componentes ven el área como consty leen, nunca escriben en ella. Tomar este enfoque limita los problemas que pueden desarrollarse.

Algunos problemas de las variables globales que deben solucionarse

Cuando se modifica el origen de una variable global, como una estructura, todo lo que lo use debe volver a compilarse para que todo lo que use la variable conozca su tamaño real y la plantilla de memoria.

Si más de un componente puede modificar la variable global, puede encontrarse con problemas con datos inconsistentes en la variable global. Con una aplicación de subprocesos múltiples, probablemente necesitará agregar algún tipo de bloqueo o región crítica para proporcionar una manera de que solo un subproceso a la vez pueda modificar la variable global y cuando un subproceso está modificando la variable, todos los cambios se completan y confirmado antes de que otros hilos puedan consultar la variable o modificarla.

La depuración de una aplicación multiproceso que utiliza una variable global puede ser más difícil. Puede encontrarse con condiciones de carrera que pueden crear defectos que son difíciles de replicar. Con varios componentes que se comunican a través de una variable global, especialmente en una aplicación de subprocesos múltiples, puede ser muy difícil entender qué componente está cambiando la variable y cuándo está cambiando la variable.

El choque de nombres puede ser un problema con el uso de variables globales. Una variable local que tiene el mismo nombre que una variable global puede ocultar la variable global. También se encuentra con el problema de la convención de nomenclatura cuando usa el lenguaje de programación C. Una solución es dividir el sistema en subsistemas con las variables globales para un subsistema particular, todo comenzando con las mismas primeras tres letras (vea esto para resolver colisiones de espacios de nombres en el objetivo C ). C ++ proporciona espacios de nombres y con C puede solucionar esto creando una estructura visible globalmente cuyos miembros son varios elementos de datos y punteros a datos y funciones que se proporcionan en un archivo como estáticos, por lo tanto, con visibilidad de archivo solo para que solo puedan ser referenciados a través de ellos. La estructura globalmente visible.

En algunos casos, la intención de la aplicación original se cambia para que las variables globales que proporcionan el estado de un solo subproceso se modifiquen para permitir que se ejecuten varios subprocesos duplicados. Un ejemplo sería una aplicación simple diseñada para un solo usuario que utiliza variables globales para el estado y luego una solicitud de la administración para agregar una interfaz REST para permitir que las aplicaciones remotas actúen como usuarios virtuales. Entonces, ahora tiene que duplicar las variables globales y su información de estado para que el usuario individual y cada uno de los usuarios virtuales de las aplicaciones remotas tengan su propio conjunto único de variables globales.

Usando C ++ namespacey la structtécnica para C

Para el lenguaje de programación C ++, la namespacedirectiva es de gran ayuda para reducir las posibilidades de un choque de nombres. namespacejunto con classy las diversas palabras clave de acceso ( private, protectedy public) proporcionan la mayoría de las herramientas que necesita para encapsular variables. Sin embargo, el lenguaje de programación C no proporciona esta directiva. Esta publicación de stackoverflow, espacios de nombres en C , proporciona algunas técnicas para C.

Una técnica útil es tener un área de datos residente de memoria única que se define como una structque tiene visibilidad global y dentro de esto structhay punteros a las diversas variables y funciones globales que están siendo expuestas. Las definiciones reales de las variables globales tienen un alcance de archivo usando la staticpalabra clave. Si luego usa la constpalabra clave para indicar cuáles son de solo lectura, el compilador puede ayudarlo a imponer el acceso de solo lectura.

El uso de la structtécnica también puede encapsular lo global para que se convierta en un tipo de paquete o componente que sea global. Al tener un componente de este tipo, resulta más fácil gestionar los cambios que afectan lo global y la funcionalidad que utiliza el global.

Sin embargo, aunque namespacela structtécnica puede ayudar a gestionar los conflictos de nombres, los problemas subyacentes del acoplamiento entre componentes que el uso de los globales introduce especialmente en una aplicación moderna de múltiples subprocesos, todavía existen.

Richard Chambers
fuente
Esta es la mejor explicación sin dudas, explica todo lo que hay que hacer. ¡Prestigio!
johndoevodka
Su idioma debe tener una regla de código para evitar que use demasiado acoplamiento de clases.
Melbourne Developer
19

Sí, pero no incurrirá en el costo de las variables globales hasta que deje de trabajar en el código que usa variables globales y comience a escribir algo más que use el código que usa variables globales. Pero el costo sigue ahí.

En otras palabras, es un costo indirecto a largo plazo y, como tal, la mayoría de la gente piensa que no está mal.

MSN
fuente
19

Si es posible, su código terminará bajo una revisión intensiva durante un juicio en la Corte Suprema , entonces debe asegurarse de evitar las variables globales.

Ver este artículo: el código del alcoholímetro con errores refleja la importancia de la revisión de la fuente

Hubo algunos problemas con el estilo del código que fueron identificados por ambos estudios. Una de las cuestiones estilísticas que preocuparon a los revisores fue el uso extensivo de variables globales desprotegidas . Esto se considera deficiente porque aumenta el riesgo de que el estado del programa se vuelva inconsistente o que los valores se modifiquen o sobrescriban inadvertidamente. Los investigadores también expresaron cierta preocupación por el hecho de que la precisión decimal no se mantiene de manera consistente en todo el código.

Hombre, ¡apuesto a que esos desarrolladores desearían no haber usado variables globales!

Casey
fuente
66
Esa fue la mejor risa que he tenido en mucho tiempo. Un verdadero ejemplo de por qué el desarrollo de código cerrado con fines de lucro es malo, ¡y un buen ejemplo de vars globales que salió mal!
Evil Spork
Lo que se establece aquí es que las variables globales se ven con desprecio. Aquí no hay nada que muestre que las variables globales fueron un problema genuino en el código. SysTest dijo que si bien el código "no fue escrito de manera consistente con las mejores prácticas habituales de diseño de software", que todavía "produciría de manera confiable resultados de prueba consistentes". Por lo tanto, no se documentó ningún daño por parte de los globales. Tal como lo veo, simplemente establecieron que, "Bueno, estos desarrolladores no practican la misma religión de codificación que el resto del mundo convencional".
LionKimbro
19

Las variables globales son tan malas como las haces, nada menos.

Si está creando un programa completamente encapsulado, puede usar globales. Es un "pecado" usar globales, pero programar los pecados es muy filosófico.

Si revisa L.in.oleum , verá un lenguaje cuyas variables son únicamente globales. No es escalable porque todas las bibliotecas no tienen más remedio que usar globales.

Dicho esto, si tiene opciones y puede ignorar la filosofía del programador, los globales no son tan malos.

Tampoco Gotos, si los usas bien.

El gran problema "malo" es que, si los usas mal, la gente grita, el módulo de aterrizaje de Marte se estrella y el mundo explota ... o algo así.

usuario54650
fuente
17
Restarle importancia a los problemas del uso de globales a un estudiante confundido no es una buena idea de la OMI.
GEOCHET
3
La filosofía del diseño no es objetiva. De ninguna manera. El hecho de que a la mayoría de los programadores no les guste algo no significa que uno nunca deba investigar ese algo. Es fácil hacer un uso general de los globales sin el fin del mundo. Déjalo hacerlo, luchar (sabiendo que lo haría) y aprender cómo.
user54650
77
Rich tiene razón. Esta respuesta no dice nada acerca de lo que es / no es malo (o como variables globales se pueden utilizar con seguridad), solamente que "no son tan malas como todo lo que Como tal, sólo resta importancia a los problemas..
JALF
44
No estoy de acuerdo con que las variables globales sean tan "malas como las haces". Creo que uno de los principales problemas, especialmente en este mundo interconectado de múltiples desarrolladores, en el que la mayoría de nosotros vivimos, trabajamos y programamos, es que las variables globales le dan a alguien MÁS la oportunidad de hacer que su código sea malo.
gariepy
@gariepy hasta saber, aunque la charla es sobre estática: D ok, eso es todo ... y mi aplicación solo tiene una o dos variables globales, esa viene con Visual Studio, DEBUG y TRACE que normalmente no usamos: D
deadManN
17

Respondería a esta pregunta con otra pregunta: ¿ Usas singeltons / Are singeltons bad?

Porque (casi todo) el uso de singelton es una variable global glorificada.

Gavin Miller
fuente
11
Estaba a punto de publicar un comentario inteligente que decía: "Solo son malos si los llamas globales en lugar de solteros", pero me ganaste.
smo
Todavía estoy tratando de descubrir qué demonios son los singletons LOL.
GeoffreyF67
1
@Geoffrey: aquí hay algunas buenas descripciones SO - stackoverflow.com/questions/11831/... y para algunos enlaces buenos: stackoverflow.com/questions/11831/...
Gavin Miller
10
Para el registro, un singleton es una variable global con un nombre glorificado de Design Patterns (tm) (lol) para que suene legítimo. Es igualmente malo por las mismas razones.
R .. GitHub dejar de ayudar a ICE
@GavinMiller ¿Estás diciendo que está bien si usas el simpleton ... ooops, el eufemismo singleton?
Juan Mendes
14

El problema es menos que son malos , y más que son peligrosos . Tienen su propio conjunto de ventajas y desventajas, y hay situaciones en las que son la forma más eficiente o la única para lograr una tarea en particular. Sin embargo, son muy fáciles de usar mal, incluso si toma medidas para usarlos siempre correctamente.

Algunas ventajas:

  • Se puede acceder desde cualquier función.
  • Se puede acceder desde múltiples hilos.
  • Nunca saldrá del alcance hasta que finalice el programa.

Algunas desventajas:

  • Se puede acceder desde cualquier función, sin necesidad de arrastrarlo explícitamente como parámetro y / o documentado.
  • No es seguro para subprocesos.
  • Contamina el espacio de nombres global y puede causar colisiones de nombres, a menos que se tomen medidas para evitarlo.

Tenga en cuenta, si lo desea, que los dos primeros pros y los dos primeros contras que enumeré son exactamente lo mismo, pero con una redacción diferente. Esto se debe a que las características de una variable global pueden ser útiles, pero las mismas características que las hacen útiles son la fuente de todos sus problemas.

Algunas posibles soluciones a algunos de los problemas:

  • Considere si en realidad son la mejor o más eficiente solución para el problema. Si hay alguna solución mejor, úsela en su lugar.
  • Póngalos en un espacio de nombres [C ++] o estructura singleton [C, C ++] con un nombre único (un buen ejemplo sería Globalso GlobalVars), o use una convención de nomenclatura estandarizada para variables globales (como global_[name]o g_module_varNameStyle(como se menciona por subrayado_d en los comentarios) )). Esto documentará su uso (puede encontrar código que usa variables globales buscando el espacio de nombres / nombre de estructura) y minimizará el impacto en el espacio de nombres global.
  • Para cualquier función que acceda a variables globales, documente explícitamente qué variables lee y cuáles escribe. Esto facilitará la resolución de problemas.
  • Póngalos en su propio archivo fuente y declare externen el encabezado asociado, de modo que su uso se pueda limitar a las unidades de compilación que necesitan acceder a ellos. Si su código se basa en muchas variables globales, pero cada unidad de compilación solo necesita acceder a un puñado de ellas, podría considerar ordenarlas en múltiples archivos fuente, por lo que es más fácil limitar el acceso de cada archivo a variables globales.
  • Configure un mecanismo para bloquearlos y desbloquearlos, y / o diseñar su código de manera que la menor cantidad de funciones posible necesite modificar las variables globales. Leerlos es mucho más seguro que escribirlos, aunque las carreras de subprocesos aún pueden causar problemas en programas multiproceso.
  • Básicamente, minimice el acceso a ellos y maximice la unicidad del nombre. Desea evitar colisiones de nombres y tener la menor cantidad posible de funciones que puedan modificar cualquier variable dada.

Si son buenos o malos depende de cómo los uses. La mayoría tiende a usarlos mal, de ahí la cautela general hacia ellos. Si se usan adecuadamente, pueden ser una gran ayuda; si se usa mal, sin embargo, pueden y van a volver a morder cuándo y con qué menos te lo esperas.

Una buena manera de verlo es que ellos mismos no son malos, pero permiten un mal diseño y pueden multiplicar exponencialmente los efectos del mal diseño.


Incluso si no tiene la intención de usarlos, es mejor saber cómo usarlos de manera segura y elegir no hacerlo, que no usarlos porque no sabe cómo usarlos de manera segura. Si alguna vez se encuentra en una situación en la que necesita mantener un código preexistente que se basa en variables globales, es posible que tenga dificultades si no sabe cómo usarlas correctamente.

Justin Time - Restablece a Monica
fuente
1
+1 para pragmatismo. Un singleton a menudo solo agrega repeticiones para convertir la instancia y refactorizar en miembros, y terminas con ... variables globales, simplemente disfrazadas con un nombre diferente. ¿Por qué molestarse, aparte de evitar el Pecado de los Globales por un simple tecnicismo? Los espacios de nombres son agradables como una barrera, pero encuentro un simple g_module_varNameStyleperfectamente legible. Para ser claros, no estoy usando globals si puedo evitarlo fácilmente, palabra clave fácilmente , porque desde que dejé de creer que deben evitarse, o más bien ofuscado , a toda costa, lo estoy pasando mucho mejor, y mi el código es (¡shock!) mucho más ordenado
subrayado_d
@underscore_d Es principalmente para tener una manera de diferenciar entre las variables globales y locales más fácilmente, y también para facilitar la localización de las variables globales al buscar su código, con la intención de evitar la confusión sobre si una variable es global o local / un parámetro / un miembro / etc. Una convención de nomenclatura estándar como la suya funciona igual de bien, siempre que sea coherente. Editando mi respuesta con la idea de la convención de nomenclatura estándar, gracias.
Justin Time - Restablece a Mónica el
1
"Para cualquier función ... documentar explícitamente qué variables" - recuerde que esta es una relación transitiva. Si la función A llama a las funciones B y C, entonces lee y escribe las variables escritas por ambos (más las que están directamente en su cuerpo)
Caleth
11

Como alguien dijo (estoy parafraseando) en otro hilo "Reglas como esta no deberían romperse, hasta que comprenda completamente las consecuencias de hacerlo".

Hay momentos en que las variables globales son necesarias, o al menos muy útiles (por ejemplo, trabajar con devoluciones de llamada definidas por el sistema). Por otro lado, también son muy peligrosos por todas las razones que le han dicho.

Hay muchos aspectos de la programación que probablemente deberían dejarse a los expertos. A veces necesitas un cuchillo muy afilado. Pero no puedes usar uno hasta que estés listo ...

Brian Postow
fuente
1
Estoy de acuerdo, si entiendes las consecuencias, está bien que rompas las reglas, pero si te encuentras haciéndolo a menudo, estás haciendo algo mal
Juan Mendes
9

Las variables globales son generalmente malas, especialmente si otras personas están trabajando en el mismo código y no quieren pasar 20 minutos buscando todos los lugares a los que se hace referencia a la variable. Y agregar hilos que modifican las variables trae un nuevo nivel de dolores de cabeza.

Las constantes globales en un espacio de nombres anónimo utilizado en una sola unidad de traducción son buenas y ubicuas en aplicaciones y bibliotecas profesionales. Pero si los datos son mutables, y / o tienen que ser compartidos entre múltiples TU, es posible que desee encapsularlos, si no es por el bien del diseño, por el bien de cualquiera que depure o trabaje con su código.

Michel
fuente
9

Usar variables globales es como barrer la tierra debajo de una alfombra. Es una solución rápida, y mucho más fácil a corto plazo que obtener un recogedor de polvo o una aspiradora para limpiarlo. Sin embargo, si alguna vez terminas moviendo la alfombra más tarde, tendrás una gran sorpresa debajo.

gnovice
fuente
metáfora perezosa sin contexto! = respuesta
underscore_d
1
@underscore_d: No estoy de acuerdo. Esta es una pregunta de discusión, a pesar de que no está etiquetada como tal (probablemente debido a su antigüedad), por lo que las respuestas como esta son perfectamente válidas, y hace un punto que aborda la pregunta de los OP.
gariepy
7

Las variables globales son malas, si le permiten manipular aspectos de un programa que solo deberían modificarse localmente. En OOP, los globales a menudo entran en conflicto con la idea de encapsulación.

Leonidas
fuente
7

Creo que tu profesor está tratando de detener un mal hábito incluso antes de que comience.

Las variables globales tienen su lugar y, como muchas personas dicen, saber dónde y cuándo usarlas puede ser complicado. Así que creo que en lugar de entrar en el meollo del por qué, cómo, cuándo y dónde de las variables globales, su profesor decidió prohibirlo. Quién sabe, podría desterrarlos en el futuro.

bong
fuente
7

Absolutamente no. Aunque abusar de ellos ... eso es malo.

Eliminarlos sin pensar por el simple hecho de ser eso ... sin sentido. A menos que conozca las ventajas y desventajas, es mejor mantenerse alejado y hacer lo que le han enseñado / aprendido, pero no hay nada implícitamente incorrecto con las variables globales. Cuando comprenda mejor los pros y los contras, tome su propia decisión.

jheriko
fuente
3
-1 Existen numerosas razones para advertir contra las variables globales: la más importante para mí es que las dependencias ocultas y las globales hacen que el código de prueba de cualquier manera predecible sea extremadamente difícil. A menos que no valore la capacidad de probar su código de manera automatizada, sugeriría que las variables globales no le causarán más que dolor. Y además, en un programa bien estructurado siempre hay alternativas.
jkp
1
lo que está diciendo es una sobregeneralización masiva, el uso cuidadoso del estado global no impide las pruebas automatizadas; de hecho, casi todas las aplicaciones tienen un estado global, ya sea que esté envuelto como instancias asignadas dinámicamente de objetos bien encapsulados o datos estáticos que están totalmente expuestos. conceptualmente no hay diferencia, todavía hay dependencias: se trata de cómo se codifican.
jheriko
1
Exactamente. No son tanto "malos" como "fáciles de romper", básicamente. Si sabe cómo usarlos sin romper nada, y cuándo usarlos en lugar de una alternativa, pueden ser útiles. De lo contrario ... no tanto.
Justin Time - Restablece a Monica
4

Las variables globales están bien en programas pequeños, pero horribles si se usan de la misma manera en programas grandes.

Esto significa que puede acostumbrarse fácilmente a usarlos mientras aprende. Esto es de lo que tu profesor está tratando de protegerte.

Cuando tenga más experiencia, será más fácil aprender cuando estén bien.

Darron
fuente
4

No, no son malos en absoluto. Es necesario mirar el código (máquina) producido por el compilador para hacer esta determinación, a veces es mucho peor usar un local que uno global. También tenga en cuenta que poner "estático" en una variable local básicamente lo convierte en global (y crea otros problemas feos que un global real resolvería). Los "globales locales" son particularmente malos.

Los globales también le dan un control limpio sobre el uso de su memoria, algo mucho más difícil de hacer con los locales. En la actualidad, eso solo importa en entornos integrados donde la memoria es bastante limitada. Algo que debe saber antes de asumir que embebido es lo mismo que otros entornos y asumir que las reglas de programación son las mismas en todos los ámbitos.

Es bueno que cuestione las reglas que se enseñan, la mayoría de ellas no son por las razones que le están diciendo. Sin embargo, la lección más importante no es que esta es una regla para llevar contigo para siempre, sino que es una regla que se debe cumplir para aprobar esta clase y seguir adelante. En la vida, encontrará que para la compañía XYZ tendrá otras reglas de programación que finalmente tendrá que respetar para seguir recibiendo un cheque de pago. En ambas situaciones puede argumentar la regla, pero creo que tendrá mucha mejor suerte en el trabajo que en la escuela. Eres solo otro de muchos estudiantes, tu asiento será reemplazado pronto, los profesores no lo harán, en un trabajo eres uno de un pequeño equipo de jugadores que tiene que ver este producto hasta el final y en ese entorno las reglas desarrolladas son para beneficio de los miembros del equipo, así como del producto y la empresa, así que si todos tienen una mentalidad similar o si para un producto en particular hay buenas razones de ingeniería para violar algo que aprendiste en la universidad o algún libro sobre programación genérica, entonces vende tu idea al equipo y escríbela como un método válido, si no el preferido. . Todo es un juego justo en el mundo real.

Si sigue todas las reglas de programación que le enseñaron en la escuela o en los libros, su carrera de programación será extremadamente limitada. Es probable que pueda sobrevivir y tener una carrera fructífera, pero la amplitud y el ancho de los entornos disponibles para usted serán extremadamente limitados. Si sabe cómo y por qué la regla está ahí y puede defenderla, eso es bueno, si su razón es "porque mi maestro lo dijo", bueno, eso no es tan bueno.

Tenga en cuenta que temas como este a menudo se discuten en el lugar de trabajo y seguirán siéndolo, a medida que evolucionan los compiladores y procesadores (y los idiomas), así lo hacen este tipo de reglas y sin defender su posición y posiblemente alguien con otra opinión le enseñe una lección seguir adelante

Mientras tanto, simplemente haz lo que diga el que más fuerte o que diga el palo más grande (hasta el momento en que seas el que grite más fuerte y lleve el palo más grande).

viejo contador de tiempo
fuente
44
¿Es esta otra forma de decir "nadie fue despedido por comprar IBM"?
Gordon Potter
1
Un buen punto es que para algunas aplicaciones el uso de variables globales puede facilitar el trabajo. En general, el uso de variables globales es una fuente de problemas con vías ocultas de acoplamiento entre secciones de fuente. Sin embargo, tener un área de memoria compartida a la que se hace referencia como global se usa para una serie de implementaciones, como interfaces de dispositivos o tal vez una tabla de parámetros global que contiene constantes de varios tipos o una tabla de salto.
Richard Chambers
4

Me gustaría argumentar en contra del punto que se hace a lo largo de este hilo que hace que el multihilo sea más difícil o imposible per se. Las variables globales son estados compartidos, pero las alternativas a los globales (por ejemplo, pasar punteros) también pueden compartir el estado. El problema con los subprocesos múltiples es cómo usar correctamente el estado compartido, no si ese estado se comparte a través de una variable global u otra cosa.

La mayoría de las veces cuando haces subprocesos múltiples necesitas compartir algo. En un patrón productor-consumidor, por ejemplo, puede compartir alguna cola segura para subprocesos que contiene las unidades de trabajo. Y puede compartirlo porque esa estructura de datos es segura para subprocesos. Si esa cola es global o no es completamente irrelevante cuando se trata de seguridad de subprocesos.

La esperanza implícita expresada a lo largo de este hilo de que la transformación de un programa de un solo subproceso a varios subprocesos será más fácil cuando no se utilizan globales es ingenuo. Sí, los globales hacen que sea más fácil dispararse en el pie, pero hay muchas maneras de dispararse.

No estoy abogando por los globales, ya que los otros puntos siguen en pie, mi punto es simplemente que el número de hilos en un programa no tiene nada que ver con el alcance variable.

Andreas Haferburg
fuente
3

Sí, porque si dejas que los programadores incompetentes los usen (lee el 90%, especialmente los científicos) terminas con más de 600 variables globales distribuidas en más de 20 archivos y un proyecto de 12,000 líneas donde el 80% de las funciones se anulan, devuelven anuladas y operan enteramente en estado global.

Rápidamente se hace imposible entender lo que está sucediendo en cualquier punto a menos que conozca todo el proyecto.

wezzman
fuente
2

El uso de variables globales en realidad depende de los requisitos. Su ventaja es que reduce la sobrecarga de pasar los valores repetidamente.

Pero su profesor tiene razón porque plantea problemas de seguridad, por lo que debe evitarse el uso de variables globales tanto como sea posible. Las variables globales también crean problemas que a veces son difíciles de depurar .

Por ejemplo:-

Situaciones cuando los valores de las variables se modifican en tiempo de ejecución . En ese momento es difícil identificar qué parte del código lo está modificando y en qué condiciones.

Mufaddal Kagda
fuente
2

Global son buenos cuando se trata de configuración . Cuando queremos que nuestra configuración / cambios tengan un impacto global en todo el proyecto .

Entonces podemos cambiar una configuración y los cambios se dirigen a todo el proyecto . Pero debo advertirte que tendrías que ser muy inteligente para usar globals.

Maaz Rehman
fuente
1

Tarde o temprano tendrá que cambiar cómo se establece esa variable o qué sucede cuando se accede a ella, o simplemente necesita buscar dónde se cambia.

Prácticamente siempre es mejor no tener variables globales. Simplemente escriba los métodos get y set de la presa, y sea flexible cuando los necesite un día, semana o mes después.

Bloodboiler
fuente
1

Por lo general, uso valores globales para los valores que rara vez se cambian como singletons o punteros de función a funciones en una biblioteca cargada dinámicamente. El uso de globales mutables en aplicaciones multiproceso tiende a generar errores difíciles de rastrear, por lo que trato de evitar esto como una regla general.

El uso de un argumento global en lugar de pasar un argumento es a menudo más rápido, pero si está escribiendo una aplicación multiproceso, que a menudo hace hoy en día, generalmente no funciona muy bien (puede usar estadísticas de subprocesos, pero la ganancia de rendimiento es cuestionable) .

Erik Ohlsson
fuente
1

En las aplicaciones web dentro de una empresa se puede utilizar para mantener datos específicos de sesión / ventana / hilo / usuario en el servidor por razones de optimización y para proteger contra la pérdida de trabajo donde la conexión es inestable. Como se mencionó, las condiciones de carrera deben ser manejadas. Utilizamos una sola instancia de una clase para esta información y se maneja cuidadosamente.

xxyzzy
fuente
1

Al final del día, su programa o aplicación aún puede funcionar, pero es cuestión de estar ordenado y tener una comprensión completa de lo que está sucediendo. Si comparte un valor variable entre todas las funciones, puede ser difícil rastrear qué función está cambiando el valor (si la función lo hace) y hace que la depuración sea un millón de veces más difícil

alaboudi
fuente
0

la seguridad es menor significa que cualquiera puede manipular las variables si se declaran globales, para que esto explique, tome este ejemplo si tiene saldo como una variable global en su programa bancario, la función de usuario puede manipular esto, así como el funcionario bancario también puede manipular Esto significa que hay un problema. Solo el usuario debe tener la función de solo lectura y retiro, pero el empleado del banco puede agregar la cantidad cuando el usuario entrega personalmente el efectivo en el escritorio. Esta es la forma en que funciona

Vamsi Pavan Mahesh
fuente
-1

En una aplicación multiproceso, use variables locales en lugar de variables globales para evitar una condición de carrera.

Se produce una condición de carrera cuando varios subprocesos acceden a un recurso compartido, con al menos un subproceso que tiene acceso de escritura a los datos. Entonces, el resultado del programa no es predecible, y depende del orden de acceso a los datos por diferentes hilos.

Más sobre esto aquí, https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded-code

Kiriloff
fuente
Para la posteridad: esto es en parte correcto en el mejor de los casos. Las "variables locales" en esta respuesta se refieren a variables locales de hilo , en lugar de las variables locales de alcance más comunes a las que se refiere el OP. Los efectos secundarios de modificar variables globales de una manera insegura en el hilo son muy diferentes de los de cambiar el estado global de una manera no concurrente.
Jules