2011-12-09 13 views

Respuesta

23

Es cuando haces algo como:

int index; 
int main (void) { 
    int index; 
    .... 
    return 0; 
} 

Lo que está advirtiendo acerca es que el index dentro main() es en realidad ocultar el global que ha declarado ante main().

Le advierte que no puede obtener la definición global mientras que la local está "activa". Ahora que no es necesariamente un problema (de ahí que sea solo una advertencia), es C perfectamente válido, pero debe ser consciente de las posibles consecuencias.

Como un aparte, (basados ​​en BSD) algunas implementaciones C definir un indexfunción en string.h que también puede causar un problema. El uso de esta función está obsoleto y no aparece en el estándar C (use strchr) pero puede ser la causa de problemas si está ejecutando (por ejemplo) Mac OS o OpenBSD (o incluso Linux bajo alguna combinación) de configuraciones #define, creo).

Hay un par de maneras de evitar esto (si es necesario).

La primera es probablemente la preferida: no use use globales. Sí, es correcto, deshazte de ellos. Raramente se necesitan, así que no me hagas venir y darte una palmada :-)

Una segunda forma que he visto es asegurarme de que estén "empacadas". Suponiendo que en realidad se necesita globales (de ninguna manera una certeza, véase el párrafo anterior), crear una estructura que los sostiene, como en el siguiente:

myglobs.h: 
    struct sMyGlobs { 
     int index; 
     // all other globals. 
    }; 
    extern struct sMyGlobs myGlobs; 

myglobs.c: 
    #include "myglobs.h" 
    struct sMyGlobs myGlobs; 

main.c: 
    #include <stdio.h> 
    #include "myglobs.h" 
    int main (void) { 
     myGlobs.index = 42; 
     return 0; 
    } 

Esto tiene la ventaja de que es obvio que se se refieren a un global y que nunca están ocultos, a menos que haga algo como definir su propia variable local llamada myGlobs.

+0

A menudo uso globales como información de estado (agregados juntos en una estructura de configuración) al escribir controladores de hardware (por ejemplo, la última configuración del hardware desde que se utilizó por última vez la API). A menudo es ventajoso/necesario guardar esta información en este tipo de situación. A lo largo de los años he escuchado innumerables argumentos para "no" usar globales, pero ¿cuáles son algunos otros casos de uso "válidos" de como lo ven? – sherrellbc

+0

Por ejemplo, vea [aquí] (https://github.com/sherrellbc/mock-OS/blob/periph_cmos_dev/mock/kernel/arch/i386/irq/irq_core/pic8259.c#L119-L123) o [aquí ] (https://github.com/sherrellbc/mock-OS/blob/periph_cmos_dev/mock/kernel/arch/i386/irq/cmos/cmos.c#L134-L138) y [aquí] (https: // github .com/sherrellbc/mock-OS/blob/periph_cmos_dev/mock/kernel/arch/i386/irq/cmos/cmos.C# L115-L121). Siguen siendo un trabajo en progreso. En este caso, necesitaba información de estado para usar en un controlador de interrupción asíncrono. Podría decirse que algo como esto no se puede hacer sin los globales. Depende del contexto, como siempre. – sherrellbc

Cuestiones relacionadas