Newsgroup: it.comp.programmare
Titolo: [C] Utilizzo della classe di memorizzazione "static"

Salve a tutto il NG,
ho una funzione C che deve ritornare un particolare elemento di un
vettore di stringhe.
Il codice è il più semplice possibile:
[BEGIN CODE SNIPPET]
char *d2c(int n) {
  static char d[][] = {"0","1","2","3","4","5","6","7","8","9"};
  return d[n];
}
[END CODE SNIPPET]
La mia domanda è la seguente:
è tecnicamente e concettualmente corretto ritornare una stringa (in
realtà, il puntatore a quella stringa) allocata come variabile interna
se è stata dichiarata static?
Senza la parola chiave static la variabile automatica d non sarebbe più
valida dopo il termine della funzione e quindi sarebbe concettualmente
sbagliato ritornare un puntatore ad un suo elemento (d[n]), giusto?
Leggo sul Kernighan-Ritchie (seconda edizione) che:
"La dichiarazione static è applicabile anche alle variabili interne. Il
campo di visibilità delle variabili interne static è limitato a una
particolare funzione, proprio come per le variabili automatiche, ma a
differenza di queste il loro ciclo di vita coincide con quello di tutto
il programma, e non con quello della funzione che le ospita. In altre
parole, le variabili static forniscono a una specifica funzione porzioni
private e permanenti di memoria."
[pag. 81]
E anche:
"Gli oggetti statici possono essere interni a un blocco o esterni a
tutti i blocchi, ma in ogni caso conservano i propri valori quando il
controllo esce e poi rientra nei blocchi e nelle funzioni. […]"
[pag. 202]
IMHO, molto sottilmente, il fatto che si dica che gli oggetti statici
"conservano i propri valori" non implica necessariamente che essi siano
accessibili anche quando il controllo non è nel blocco che li contiene.
Mi viene quindi da pensare che questa possibilità dipenda dalla
particolare scelta implementativa operata dal compilatore che si sta
utilizzando, e non da una specifica del linguaggio.
In questo caso però, dichiarare una variabile interna static non
servirebbe al fine di poter utilizzare tale variabile anche all'esterno
della funzione o blocco che la ospita.
Siete d'accordo?
-- 
Andrea "XFox" Govoni
AIM/iChat/ICQ: 
xf...@mac.com
Yahoo! ID: xfox82
Skype Name: draykan
PGP
KeyID: 0x212E69C1
Fingerprint: FBE1 CA7D 34BE 4A53 9639  5C36 B7A0 605F 212E 69C1

 [END CODE SNIPPET]
Accidenti, mi è scappato un errore, la seconda riga del codice dovrebbe
essere:
static char d[][2] = {"0","1","2","3","4","5","6","7","8","9"};
.
-- 
Andrea "XFox" Govoni
Codice Wii: 0294 5787 0060 3021


 se è stata dichiarata static?
Le variabile automatiche vengono allocato nello stack, ogni funzione
crea un suo stack
e viene distrutto quando la funzione termina.Nel caso volessi rendere
una variabile automatica permanente,
ricorri a 'static'.Le variabili static vengono allocate nel campo data
segment.
include <stdio.h>
void prova(){
static int i=1;
printf("%d\n", i++);
}
int main()
{
int i;
for(i=0;i<10;i++)
        prova();
return 0;
}
Come vedi il campo data è scrivibile e permanente.

 segment.
Grazie della risposta, anche se sarebbe stato gradito un commento anche
a questo paragrafo:
"IMHO, molto sottilmente, il fatto che si dica che gli oggetti statici
"conservano i propri valori" non implica necessariamente che essi siano
accessibili anche quando il controllo non è nel blocco che li contiene."
A scanso di equivoci, non dico che tu non abbia ragione, ho anche
trovato un esempio di codice sullo stesso Kernighan-Ritchie (pag. 111,
seconda ed.) concettualmente identico alla mia funzione di esempio.
Saluti,
-- 
Andrea "XFox" Govoni
Codice Wii: 0294 5787 0060 3021
AIM/iChat/ICQ: 
xf...@mac.com


 
A me e' capitato di scrivere funzioni che abbiano definito al loro 
interno un array statico di stringhe per tornarne il puntatore.
Nel caso specifico erano degli array coi nomi dei mesi e dei giorni 
della settimana in tre o quattro lingue diverse.
Codice compilato e utilizzato su piu' sistemi senza alcun problema.
Un oggetto statico definito all'interno di una funzione non e' visibile 
all'esterno di essa, ma il puntatore si, e l'oggetto non viene distrutto 
all'uscita della funzione, quindi e' possibile scrivere codice in questo 
modo.
Naturalmente non e' una pratica pulitissima e quindi e' una cosa da 
evitare se possibile, oppure va utilizzata con piena consapevolezza.

 accessibili anche quando il controllo non è nel blocco che li contiene."
Non ho commentato la frase perchè non la comprendo a fondo.
Tu allochi tot memoria nel data segment, mantenendo un puntatore a
quest'aria,
che ripeto rimane permanente fino alla chiusura del programma, perchè
questa non dovrebbe
essere accessibile ? Per controllo cosa intendi ?
Salut.

 Per controllo cosa intendi ?
Ho usato la terminologia del Kernighan-Ritchie. Non ne ho letto la
definizione (utilizzo il libro più come riferimento, non l'ho ancora
letto top-down) ma suppongo si intenda che il controllo è in una certa
funzione (o blocco) del programma quando il processore sta eseguendo le
istruzioni di quella certa funzione (o blocco).
Ora non riesco a trovare un modo semplice per spiegarlo… '-_-
Ola,


 wrote:
[cut su tutto]
Ti consiglio di porre questo genere di domande su it.comp.lang.c dove
sono molto ferrati sullo standard C e ti sapranno senz'altro dare una
risposta chiara in poco tempo.
Saluti,
The Librarian

 seconda ed.) concettualmente identico alla mia funzione di esempio.
1. il K&R è un libro, non lo standard del linguaggio
2. lo standard fa testo, il K&R non necessariamente
3. lo standard è spesso scritto con il culo e in modo ambiguo
4. lo standard in questo caso è chiaro chiaro e dice:
An object whose identiﬁer is declared with external or internal linkage,
or with the 
storage-class speciﬁer statichas static storage duration. Its lifetime
is the entire 
execution of the program and its stored value is initialized only once,
prior to program 
startup. 
-- 
blog:  
http://www.akropolix.net/rik0/blogs
 | Uccidete i filosofi,
site:  
http://www.akropolix.net/rik0/
      | tenetevi riso e
forum: 
http://www.akropolix.net/forum/
     | bacchette per voi.

 altro codice per ripristinarli all'ingresso.
Hanno già inventato la virtual memory, e implementata in ogni
kernel..e dall'era dei tempi
le variabili globali e le variabili static sono stato sempre nel data
segment.
Ti consiglio di studiarti la gestione della memoria di un processo e
addentrarti poi nello
studio spefico del tuo ambiente di sviluppo.
Salut.

 risposta chiara in poco tempo.
Non avevo proprio notato che ci fosse un gruppo più specifico, scusate.


 kernel..
...quindi?


 or with the […]
Giusto per curiosità, puoi postare anche il link da cui hai preso il
testo citato?
Grazie.


 Non avevo proprio notato che ci fosse un gruppo più specifico, scusate.
Non ti devi scusare ;-)
Puoi postare anche qui, sei IT.
E' solo che qui si parla di programmazione in generale. Se ti
interessa un aspetto di un particolare linguaggio di programmazione,
ti conviene rivolgerti ad un newsgroup dedicato dove e' piu' probabile
che sappiano risponderti in modo adeguato.
Saluti,
The Librarian

 testo citato?
Lo ho preso dallo standard. E non posso postare link perchč lo standard
si compra e si paga, ergo non č disponibile su web (in nessun posto che
io conosca e che sia liberamente accessibile).
-- 
cc = callcc {|cc| cc.call cc}; cc.call cc

 
Se non hai esigenze specifiche puoi far riferimento alle versioni draft. 
L'ultimo draft dello standard committee lo trovi qui: 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
la frase citata è al paragrafo 6.2.4.
Per altre informazioni sullo standard: 
http://clc-wiki.net/wiki/C99
Remo.D

   
commento alle delibere del comitato:
http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

 Per altre informazioni sullo standard: 
http://clc-wiki.net/wiki/C99
Bravissimo. Alle draft non avevo pensato, in effetti. L'altro link non
lo conoscevo neppure. :)
