PDA

View Full Version : [C] valore variabili globali


grollagrolla123
09-06-2009, 16:26
Scusate ma non riesco a trovare la soluzione a un quesito.
Con la dichiarazione di una variabile globale intera in C,senza inizializzazione, ha valore Zero?
Ho provato con la stampa dei valori con la printf() è stampa sempre zero mentre stampando una variabile automatica mi da valori a caso.

Dipende dal'implementazione o è una azione non definita dallo standard C89?

int b;

main(){
int x;
static int k;

printf("b==%d x==%d k==%d\n", b, x, k);
}

output sarà

b==0 x==498880 k==0

mi sapete spiegare perché?

tapper
09-06-2009, 17:16
mmm da quel che ricordo se non la initializzi la variabile ha valore "casuale" (cioè quello che è presente in memoria allo stesso indirizzo).
Se quella globale viene automaticamente inzializzata a zero dipende dall'implementazione del compilatore.

Ciao



------------------------------
Tetti Parma (http://www.sandrinilegnami.com/1024/tetti1.htm)

grollagrolla123
09-06-2009, 17:42
ho sempre saputo che le variabili globali in C sono automaticamente inizializzate a zero.

beh mi era sfugito, immagino sia così ,per lo stesso motivo, anche le variabili con static.

yorkeiser
09-06-2009, 20:05
Non c'è un comportamento standard: alcuni compilatori oltre ad allocare spazio in memoria resettano anche il valore, altri allocano soltanto i byte necessari, quindi la variabile assume il valore contenuto in memoria in quel momento (casuale).
Per questo motivo, è OTTIMA abitudine inizializzare sempre una variabile prima di utilizzarla.

fero86
09-06-2009, 21:04
confermo, anche a me risulta che il valore di una variabile non inizializzata sia arbitrario e non determinato dallo standard; per quanto riguarda esclusivamente le variabili globali quello che accade su Windows é che il compilatore le mette in una sezione dati non inizializzati che ha raw size nulla e virtual size non nulla, e quando il modulo eseguibile viene caricato in memoria il Virtual Memory Manager di Windows inizializza di default tutte le pagine allocate per tali sezioni riempiendole di zeri; quindi su Windows le variabili globali non inizializzate dovrebbero essere sempre nulle, ma si tratta di un comportamento assolutamente non portabile.

||ElChE||88
09-06-2009, 21:15
C99 standard 6.7.8.10: (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf)
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.

fero86
10-06-2009, 01:04
C99 standard 6.7.8.10: (http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf)
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules. visto che parla di variabili automatiche e statiche immagino stia parlando di variabili locali, quindi non c'entra nulla.

||ElChE||88
10-06-2009, 01:34
visto che parla di variabili automatiche e statiche immagino stia parlando di variabili locali, quindi non c'entra nulla.
6.2.2.3
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

6.2.4.3
An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

6.7.8.10
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules,

wingman87
10-06-2009, 02:53
C'è da dire però che lo standard C99 non è seguito da tutti i compilatori e a volte non è implementato completamente.

||ElChE||88
10-06-2009, 08:44
C'è da dire però che lo standard C99 non è seguito da tutti i compilatori e a volte non è implementato completamente.
Qualcuno ha detto Microsoft? :asd: (in realtà anche il GCC non lo ha implementato completamente (http://gcc.gnu.org/gcc-4.4/c99status.html), ma mi sembra che siano ad un altro livello)
Comunque probabilmente quei punti ci sono anche negli standard precedenti... solo che non ho trovato pdf consultabili gratuitamente. :fagiano:

fpucci
10-06-2009, 12:28
In linea generale credo che dipenda dall'implementazione del compilatore.

Personalmente cerco di attenermi alle buone regole di programmazione che impongono SEMPRE E COMUNQUE di inizializzare una variabile prima di utilizzarla, a meno che essa non venga assegnata successivamente prima dell'utilizzo. In altri termini, non dare nulla per scontato sul comportamento del compilatore, anche perché se poi il codice deve essere "portato" su un altro compilatore e/o sistema operativo non è detto che si comporti nello stesso modo.