2012-08-14 26 views
5

Sé que las variables globales son malas y deben evitarse en la medida de lo posible. Sin embargo, al escribir programas paralelos con MPI, por ejemplo, algunas variables solo se inicializan una vez y nunca cambian (el número de esta tarea, el número total de tareas, etc.). ¿Todavía se considera una mala práctica tener estas variables como globales? Como prácticamente necesita acceso a estas variables todo el tiempo, parece tonto hacer una clase para ellas en main, y pasarle un puntero al 99% de todas las funciones del programa. Mi enfoque hasta ahora ha sido ocultarlos en un espacio de nombres mpi_glob (para el caso de C++, supongo que no me molestaría en ponerlos en una estructura en C para emular un espacio de nombres). Supongo que la pregunta también se aplica a otras variables de solo configuración, como un sistema de unidades, etc.Variables globales y MPI

Respuesta

5

La razón por la cual las variables globales "son malas" es que introducen el acoplamiento entre archivos fuente separados que pueden ser difíciles de identificar y rastrear. En particular, si una variable global tiene un estado inesperado en algún punto del programa, puede ser difícil averiguar dónde se modificó.

Reemplazar variables globales con variables locales que pasan por referencia a cada función en el programa no elimina ese problema. En términos de diseño, se trata de "datos vagabundos", es decir, datos que deambulan aunque no sean necesarios.

Ahora, el punto aquí es que, como usted sugiere, los datos que se inicializan una vez y nunca han cambiado no tienen los problemas que hacen que las variables globales sean "malas". Como el problema no existe, la solución no es necesaria.

0

No se debe seguir ninguna regla por encima de un precipicio, y los detalles dependen completamente del tipo de programa que se escribe.

Si su programa es relativamente pequeño (o usted es el único que lo escribe/mantiene), entonces es probable que deje las variables "globales" en un espacio de nombres especial. Al menos de esa manera no es probable que los sigas o pisotees accidentalmente en un ámbito local en alguna parte. Eso suponiendo que no estás haciendo algo como esto sin embargo:

using namespace mpi_glob; 

Cuál es poco diferente de sólo tener las variables globales en un archivo en algún lugar y no los protege mucho.

Si hace que su programa sea más claro y fácil de entender mediante el uso de variables globales, entonces úselos. Si es posible mantenerlos locales, manténgalos localmente, ya que generalmente hará el mantenimiento más simple a largo plazo.

0

Supongo que Singleton debería ayudarlo a manejarlo mejor, por lo que no tiene que pasar el puntero. Prácticamente, mpi_glob hace lo mismo, Singleton es una forma más acostumbrada.

Alternativamente, aún puede recurrir a variables globales, no son malas como tales. Si desea hacer hincapié en la asignación de una sola vez se pueden declarar const y los puso a través de inicializador estático como sigue:

const int number_of_tasks = get_preconfigured_number_of_tasks(); 

Si las variables globales se utilizan para mantener compilar constantes de tiempo, entonces es perfectamente posible reemplazarlos con enum miembros o preprocesador define. Hacerlo disminuirá en el compilador, ya que puede usar el valor inmediato in situ sin acceso a la memoria.


El crédito va a Pete Becker por señalar los problemas de Singleton en su comentario. Si esos problemas también te molestan, entonces se puede tomar un enfoque totalmente diferente.

¿Recuerda cómo se implementan los programas Java? Hay una clase principal con método principal y todo el trabajo del programa se ejecuta desde dentro de ese método principal. Main sigue siendo función de miembro, es decir, puede acceder de forma exclusiva a algunos campos privados de la clase principal (tienen que ser estáticos en el caso de Java, pero este no es el punto principal aquí).

Podemos ampliar el concepto a la implementación de tipo Command. La diferencia con Java convencional es que el equivalente de su método principal no es estático y sus variables globales con valores específicos para el programa contenido son variables de miembros no estáticos. Todas las funciones que necesitan acceso a datos de estado globales se deben convertir en funciones miembro. Esto es posible, porque el método principal también es función de miembro.

De esta manera, creo que puede lograr una mejor encapsulación y seguridad de los datos.

+1

Un singleton es excesivo para las constantes y proporciona solo una ilusión de seguridad para los datos globales. El problema con los datos globales es que se puede modificar desde cualquier archivo fuente, por lo que es difícil ver dónde se realizó un cambio en particular. Convertirlo en singleton no cambia eso. El único beneficio que conozco al usar un singleton es que reduce el orden de los problemas de inicialización. Pero el orden de los problemas de inicialización surge del uso excesivo de los globales; la reducción del uso de globales también reduce estos problemas, así como la reducción de los problemas de depuración que presentan los globales. –

+0

@PeteBecker Estoy de acuerdo con usted con respecto al control de datos, especialmente si singleton es solo un objeto tonto sin getters/setters. En este caso, Singleton no pretende traer ventajas que OP no solicitó. Lo he dibujado solo para representar un modo más común, lo que los programadores comunes como yo esperarían. Sin duda es un exceso de constantes, por eso hay otras alternativas. –

+0

no importa si el objeto que obtienes de un singleton tiene getters y setters. Todavía son datos globales. Los getters y setters no son más útiles y no menos útiles de lo que serían con datos globales simples. –