Newsgroup: it.comp.lang.c
Titolo: Strutture e funzioni

Ciao a tutti,
desidererei sapere in che modo il C gestisce le strutture, soprattuto in che
modo vengono gestiste quando le funzioni devono ritornare valori di tale
tipo.
Purtroppo ho avuto professori che sostenevano che le funzioni possono
operare solamente con tipi di ritorno scalari.
Come ho avuto modo di vedere dal punto di vista sintattico non c'è molta
differenza rispetto al codice che già scrivevo con una variabile di tipo
semplice, ma interessa soprattutto sapere in che modo è possibile effettuare
operazioni come nel seguente esempio:
struct a
    {
     int a, b;
     } d, e;
struct a funzione(void)
    {
     return e; // dove viene depositato tale valore di ritorno?
     }
int main(void)
    {
     d = e; // in che modo avviene la copia?
     d = funzione();
     return 0;
     }
Grazie.

      }
Ciao
Giuseppe

 Giuseppe
Ciao.

 >
Questo post credo che chiarisca il dubbio
http://groups.google.com/groups?q=function+returning+structures&hl=it&selm=1995Jun11.173037.16199%40sco.com&rnum=1
C:\>iao Angelo
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG


Quando viene invocata la funzione in main() il mio compilatore non fa altro
che fare un push dell'indirizzo della struct d nello stack.
In funzione() viene caricato il puntatore passato nello stack, quello della
struct e, la lunghezza della struct e poi viene eseguita una chiamata a
memcpy().
La struttura e quindi non viene appoggiata da nessuna parte.
La copia delle strutture d=e viene eseguita in modo analogo.
Probabilmente questo e' stato introdotto con lo standard 99, in quanto sul
K&R che ho io (= molto vecchio) viene chiaramente specificato che "...Questo
implica che alle strutture non si puo' assegnare o non si possono copiare
come un tutt'uno, e che non possono essere passate a funzioni o ritornate da
esse". Segue la frase sibillina "Queste restrizioni saranno eliminate in
versioni future".
Ciao
Giuseppe


http://groups.google.com/groups?q=function+returning+structures&hl=it&selm=1
995Jun11.173037.16199%>
40sco.com
&rnum=1
Dubbio quasi risolto. Però rimane ancora un'interrogativo, cosa s'intende
per valore di una struttura?  Come sono abituato a ragionare una struttura
per definizione non contiene niente se non grazie ai data member, gli
effettivi "contenitori di valori".
Comunque grazie per l'auto che mi è stato assai utile.

 Giuseppe
Ringrazio a braccia aperte e saluto.

effettivi "contenitori di valori".
Una strtuttura e' uno spazio di memoria abbastanza grande da contenere
le informazioni che gli indichi.
Questo spazio viene allineato per eccesso alla dimensione della
"parola" della macchina su cui lavori (il K&R lo dice da qualche
parte, non ricordo dove pero').
Esempio:
Se avessi parole macchina di 8 byte e una struttura del tipo:
struct {
    type_one one;  // dimensione: 1 byte
    type_two two;  // dimensione: 5 byte
}
Probabilmente ti troveresti 8 byte allocati in questo modo:
+---+---+---+---+---+---+---+---+
|   |                   |   |   |
+---+---+---+---+---+---+---+---+
 one         two         unused
Riferimenti:
http://developer.gnome.org/doc/API/2.0/glib/glib-standard-macros.html
oppure guarda il file glib/gmacros.h
Qui ti fanno vedere che accedono ai singoli membri delle struct
semplicemente conoscendone l'offset dall'inizio... se non fosse un
unico blocco di memoria una cosa simile non sarebbe possibile.
Dato questa premessa per un compilatore ritornare una struct e' come
ritornare un tipo scalare, unica eccezione che avra' piu' lavoro da
fare perche' generalmente la struct avra' una dimensione maggiore.
Il fatto che in alcuni casi si preferisca ritornare un puntatore a una
struttura allocata dinamicamente dalla funzione e' solo una scelta
implementativa che dipende dal tipo di applicazione che cerchi di
fare.
Nota: era in pascal (almeno pascal nella sua accezione piu' standard)
a quando mi avevano insegnato che non potevi (o non dovevi?) ritornare
una struttura.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 parte, non ricordo dove pero').
In realta' gli allineamenti vengono fatti per questioni di velocita'
di accesso ai membri della struttura. Non c'e' nessun obbligo, alcuni
compilatori (gcc se non sbaglio) consentono di avere strutture con
un numero di byte esattamente uguale a quello che avrebbero occupato
i singoli elementi da soli.
A pag. 176 della versione italiana K&R II ed. dice
"Se, per esempio, un char occupa un byte ed un int ne occupa quattro,
la struttura
   struct {
      char c;
      int  i;
   };
potrebbe anche occupare o byte invece di cinque".
Pertanto non sembra ci sia l'obbligo di allineamento e' una
possibilita' di ottimizzazione in piu' lasciata al compilatore.



Secondo me , piu' che ottimizzazione e' una cosa specifica del sistema
target.
Certi microprocessori non accettano di caricare word o doubleword da
indirizzi dispari.
Ciao
Giuseppe

 indirizzi dispari.
Non lo metto in dubbio, in ogni caso la mia voleva essere una
puntualizzazione sul fatto che l'allineamento dei dati non e', in
generale, un obbligo, ma una possibilita'.
Che poi quando ho risposto avessi in mente l'x86... :-)


i singoli elementi da soli.
Mi sono mangiato una parola, scusate... avrei dovuto dire
"generalmente allineato" (o "che puo' essere allineato").
