Newsgroup: it.comp.lang.c
Titolo: Cercare il pelo nell'uovo:return

Salve a tutti, domanda semplice:
se ho una funzione void funz(void);
devo scrivere nella stessa , sempre
e comunque l'istruzione return?
o posso anche ometterla?
Grazie a tutti
Ciao


prova!

 prova!
Per piacere,  evitiamo di dare  questi consigli, finisce  che qualcuno
prova a compilare
void main(void)
{
}
e pensa che  sia corretto solo perche' il  compilatore non gli segnala
niente.
In una funzione  che ritorna void, il return  si puo' omettere perche'
cosi' e'  previsto  dallo  standard [1], non  perche'  la  mattina  un
programmatore di compilatori  si sveglia e decide che  per lui va bene
cosi'.
La risposta giusta non e' "prova", ma "PROVA A CERCARE", su google (ad
es.)".
C:\>iao Angelo
[1] Cercando su 
groups.google.com
 si trova
    "Reaching  the  } that  terminates  a  function  is equivalent  to
     executing a return statement without an expression."
    Purtroppo questa frase non e'  riportata  nello  standard che ho a
    disposizione: o e' presente nello standard precedente o e' presen-
    te in un qualche  draft.  Lo standard attuale e' molto piu' vago e
    riporta  nella sezione  6.8.6.4  "The return statement"  "A return
    statement terminates execution of the current function and returns
    control to its caller.  A function may have  any number  of return
    statements."
 
    Nella sezione 6.9.1  "Function definitions" non  ho trovato nessun
    obbligo alla presenza dello statement return.  Trovo invece questo
    esempio:
 
        void g(int func(void))
        {
        /* ... */
           func() /* or (*func)() ... */
        }
 
    e non vedo return prima della parentesi che chiude il body di g().
 
    Visto che "may have any number" puo' significare  che potrebbe non
    averne nessuno, ne concludo che la sua presenza  non e' obbligato-
    ria in tutti i casi: funzioni che ritornano void sembrano rientra-
    re in questi casi.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 niente.
Haia ahia ahia :-) mi sento preso un pochino in causa ! (vedi qualche post
+ su ) Mi sembra addirittura di ricordare che il Tubo c si incavolasse un
pochino se si provava a terminare la una funzione dichiarata void con un
return val;

 niente.
Io non mi trovo affatto daccordo.
Penso che il provare se funziona un pezzo di codice, soprattutto se
piccolo, consenta di dissipare molto velocemente dubbi.
es° stupido:
quando dichiaro char gino[]="pippo" la stringa conclude con uno '\0'?
Se cerco su google perdo in media piu' tempo, per quesiti di tal fatta.
E tra parentesi, a me il compilatore, per void main (void){}, segnala
warning: return type of `main' is not `int'
che mi fa capire che il codice non e' perfetto.
Ciao,
Riccardo
-- 
-=Riccardo Galli=-
 _,e.
s~  ``
 ~@.   ideralis Programs
.   ol 
 `**~  
http://www.sideralis.net

 niente.
Io non mi trovo affatto daccordo.


 Se cerco su google perdo in media piu' tempo, per quesiti di tal fatta.
Quanto tempo perdi nel caso in cui ti trovi davanti ad una situazione
che su un compilatore funziona in un modo e su un altro in modo diverso?
Purtroppo l'apprendimento e' un'attivita' lunga che continua per tutta
la vita. Di solito le scorciatoie prima o poi si pagano.
Io comunque non ho impiegato una vita. Ho impiegato piu' tempo a scrivere
e formattare la risposta. Andare su 
groups.google.com
 e scrivere in
advanced search "void function return statement" in "with all of the
words" e "*.c.*" in newsgroups non e' che ci voglia tanta fantasia.
La risposta si trova in
Re: explicit return in void function()
e' la terza della lista. Tempo impiegato 2 sec. netti (e 1.33 sec sono
stati necessari affinche' google mi desse la risposta).
C:\>iao Angelo


 return val;
Ahi ahi ahi. Se la funzione è void, non puoi farle ritornare certo un
valore, ma ciò non vuol dire che non puoi comunque mettere una return!!
corretto (anche se return è opzionale)
void f(void)
{
    ...
    return;
}
non corretto (f() non può ritornare un valore!!!)
void f(void)
{
    return 0;
}

piccolo, consenta di dissipare molto velocemente dubbi.
...e di farne venire tanti altri, in molti altri casi ;-)
Bisogna, difatti, stare attenti a tutti quegli aspetti dipendendenti
dall'implementazione.


Giustissimo ma......
......google?????
Kernighan e Ritche.
Comprate il libro.
Queste sono cose da deficenti....è roba da scuola elementare!
Ma per favore
Lorenzo .... comprati IL manuale, o vuoi imparare un linguaggio  (come il C)
sui newsgrp?
Ringhio


<cut>

 dovere di chiarire....
Infatti il discorso non era del tutto diretto a te....figurati
Ciao

 'return value;' in una funzione void il compilatore si incazza", mi sento >
in dovere di chiarire....
---- test.c ----
void fnc(void)
{
    return 10;
}
int main( void )
{
   fnc();
   return 0;
}
warning C4098: 'fnc' : 'void' function returning a value
Compiler Warning (level 1) C4098
'function' : void function returning a value
A function that was declared with a return type of void contained
a return statement that returned a value.
Dove sarebbe la cazzata? Se il compilatore si "incazza" fa solo il suo
dovere.
C:\>iao Angelo



Usa una stringa no?
(Char *)
qualche dubbio potrebbe venire ;-)
C:\>iao Angelo


 dovere di chiarire....
Non mi sembra di aver scritto una cazzata, ma una cosa giusta, lo hai
chiaramente spiegato nei piccoli esempi... Magari intendi una cazzata perchè è
una cosa che dovrebbero sapere tutti ma solitamente le cose che si sanno sono
sempre cazzate e asserire che " Queste sono cose da deficenti....è roba da
scuola elementare! " serve a poco... (questo per quanto riguarda ciò che ha
scritto Lucagiuseppemannella) ma è molto indicato il suo consiglio di un buon
testo... Cordialmente Dave.


K&R ? certo sono solo gli inventori del linguaggio! tranquillo....resta
nella tua ignoranza!
(Char *)? te la sei legata al dito? che non si può sbagliare neanche
un'uppecase?
Non ho tempo da perdere..
Saluti

 Se cerco su google perdo in media piu' tempo, per quesiti di tal fatta.
Ciao Riccardo, scusa ma non sono molto daccordo con te, se tu dichiari char
gino[]="pippo"; , se non ricordo male la stringa non conclude con '\0' ma
puň capitare che questa stringa venga allocata in uno spazio di memoria dove
tutto intorno ci sia 0 per cui se tu richiami l'istruzione
printf("%s",gino); non hai nessun problema e ti stampa "pippo" e questo
magari per 10 volte consecutive, ma mettiamo il caso che lo spazio intorno a
gino venga allocato e riempito con qualcosa diverso da zero richiamando
printf va tutto a pallino, per dovere di cronaca se si vuole che gino temini
con  '\0' dovrň dichiararlo cosě: char *gino="pippo"; a questo punto non ho
piů problemi.
Giuste o sbagliate che siano le mie affermazioni la mia piccola morale č
questa: č giusto provare ma con davanti un buon testo ! Cordialmente Dave.

K&R ? certo sono solo gli inventori del linguaggio! 
Solo R, K ha collaborato a Unix.


Giustissima puntualizzazione...ma questo non toglie
nulla al libro!
Non mi toccate il K&R....

gino[]="pippo"; , se non ricordo male la stringa non conclude con '\0' 
Non e` cosi`.
"pippo", in questo caso, equivale a {'p','i','p','p','o','\0'}

 tutto intorno ci sia 0 per cui se tu richiami l'istruzione
Tutto intorno c'è 0?
"pippo" è una stringa........una seq. di caratteri. L'ultimo è sempre '\0'

lucagiuseppemannella ha scritto:

Allora anche char gino[10]="pippo";  è una sequenza di caratteri ma in questo
caso l'ultimo non è zero se non lo specifichi...

lucagiuseppemannella ha scritto:

Allora anche char gino[10]="pippo";  è una sequenza di caratteri ma in questo


 caso l'ultimo non è zero se non lo specifichi...
   L'ultimo forse no, ma il sesto (gino[5]) lo e` di certo.
-- 
Alla prossima,
Marco

 caso l'ultimo non è zero se non lo specifichi...
No gino[10]="pippo" non ha senso perchè:
1) "pippo" è una stringa
2) gino[10] è un carattere
gino[10]='c' ha senso.
Mi spiace ma non capisco cosa vuol dire la tua frase.
Spiegati meglio.

 gino[10]='c' ha senso.
   Anche questo ha senso ma, se controlli bene l'articolo originale, 
sono due cose diverse.
-- 
Alla prossima,
Marco

 Non mi toccate il K&R....
Se proprio vogliamo essere pignoli, il libro non e' perfettamente conforme 
al C89 (visto che e' uscito prima che lo standard fosse definitivo) e meno 
che mai al c99, quindi non lo puoi in alcun modo considerare come unica 
fonte di informazione (per quanto possa essere un bel libro).
Potresti trovare che il K&R ti dice una cosa, ma chiedendo su questo NG 
potresti scoprire che era uno degli aspetti non coperti dal libro, ma 
introdotti nello standard (parlo ancora del C89 of course).
-- 
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."

 definito come vettore di caratteri ed inizializzato con il letterale
Giusto...non avevo letto char ....si tratta di una def.
ok

 piccolo, consenta di dissipare molto velocemente dubbi.
Dovresti:
- compilare il pezzo di codice
- se tutto funziona come ti aspetti controllare:
  - che non sia un aspetto che lo standard lascia come undefined behaviour 
    (sperando che sia scritto giusto)
  - controllare se il compilatore nello specifico caso si attiene o meno 
    allo standard o se il lavoro non e' ancora ultimato (ha senso piu' che 
    altro in C99, al C89 si attengono praticamente tutti i nuovi 
    compilatori)
Visto che alla fine devi sempre leggere la documentazione, tanto vale farlo 
prima di provare :)


lucagiuseppemannella ha scritto:

Ragazzi inizio ad avere le idee un pochino confuse...
char gino[10]="pippo";
char gino[]="pippo";
char *gino="pippo";
da quanto ricordo, il primo caso riserva 10 bytes in memoria  e inizializza i
primi 5 con pippo senza '\0' al termine, il secondo riserva lo spazio
occupato dalla stringa tra virgolette senza '\0' (questo mi avete già
spiegato che non è vero), il terzo riserva lo spazio occupato dalla stringa
tra virgolette con '\0'. Che cosa c'è di vero in quanto ipotizzato da me
sopra ? (veramente sono cose che mi pare di aver letto non ricordo dove)  nel
caso che ci siano delle differenze (sicuramente ci sono) quali sono ???
Salutoni a tutti Dave.

 char *gino="pippo";
   Definisce un puntatore a carattere e lo inizializza con l'indirizzo 
del letterale "pippo" (il quale, ancora una volta, contiene come sesto 
elemento lo zero).
   Le prime due forme definiscono una stringa che potra` essere, 
nell'ambito delle sue dimensioni, adeguatamente modificata, la terza no.
-- 
Alla prossima,
Marco

 gino[10]='c' ha senso.
Stiamo arrivando a livelli BASSISSIMI!!!!
Ho letto questo thread ed e' pieno di cose stupide inutili e davvero banali.
E' inoltre pieno di errori, normale direte voi, siamo umani. SI!
Ma sono errori scritti con la presunzione di chi non sbaglia mai e questo da
fastidio: ARHGGGGGGGGHRRR!
Tommy
P.S.
gino[10]="pippo" ha senso e ........ beh, un altro giorno!
l

 caso che ci siano delle differenze (sicuramente ci sono) quali sono ???
Una cosa alla volta:
"pippo" e' una costante stringa. Questa contiene gia' di per se
[P][I][P][P][O][\0] (dove [ ] e' un byte).
char gino[10]="pippo"; dichiara un array di 10 caratteri (da 0 a 9) ed
inizializza i primi 6 con i 6 bytes di "pippo".
gli ultimi 4 bytes possono contenere qualsiasi cosa, non vengono toccati!
char gino[]="pippo"; dichiara un array di 6 caratteri, i 6 della stringa:
[P][I][P][P][O][\0]
char *gino="pippo"; dichiara un puntatore ad una costante stringa. In fatti
in questo caso (ma non solo in questo) "pippo" e' un indirizzo! In pratica
se l'indirizzo di "pippo" e' 0x0FAAADD8 allora gino puntera' a quel
indirizzo. Gino potra' inoltre essere utilizzato al posto della costante
stringa per stampare la stringa a video etc....
Se ho sbagliato, significa che tutti i thread banali scritti sopra mi hanno
confuso le idee.... ah, sono fuori casa e non ho controllato da nessuna
parte, quindi caso mai aspetto una correzzione di Andrea Laforgia, storico
rivale ;-)
Tommy

 gino[10]="pippo" ha senso e ........ beh, un altro giorno!
gino[10]="pippo" lo dico e lo ripeto non ha senso.
HA SENSO "char gino[10]"....infatti non avevo letto "char" davanti a
gino[10].

al C89 (visto che e' uscito prima che lo standard fosse definitivo) [...]
Esatto e, tra l'altro, sarebbe bene accompagnarne la lettura con i
vari Errata Corrige pubblicati dopo la ratifica dello standard (come
quello in cui si specifica, p.e., che il ritorno di malloc non va
castato, mentre nel testo c'e` scritto il contrario).

Ciao Tommy e grazie a  tutti per le varie delucidazioni, ora mi è tutto chiaro
tranne che una cosa, nell'attesa delle vostre risposte, non essendo neppure io
a casa e non avendo nessun testo attendibile a portata di mano ho dato uno
sguardo a qualche tutorial in giro per la rete e mi sono imbattuto in tale
affermazione:
 * tipo nome[dimensione] = {lista argomenti};
 *
 * lista argomenti = I valori da dare agli elementi dell'array, separati
 * da una virgola. Il primo valore corrisponde al primo elemento, e cosi'
 * di seguito. Si possono mettere tutti gli elementi o solo una parte, ad
 * esempio possiamo inizializzare solo 5 elementi di un array di 10
 * elementi, in tal caso i restanti 5 saranno azzerati.
 * Esempio:
 *
 * int provina[5]={10,20,30,40,50};
 *
 * In questo caso abbiamo inizializzato tutti gil elementi dell'array.
 * Attenzione al fatto che se non si inizializza un array, ne' ci si
 * scrive dentro, i suoi contenuti non sono degli zeri, bensi' valori a
 * caso presenti in quel punto della memoria!
non ho resistito ho ripreso in mano il buon vecchio turbo c e da qualche prova
effettuata tutto torna a meraviglia, anche se tu avevi scritto:
char gino[10]="pippo"; dichiara un array di 10 caratteri (da 0 a 9) ed
inizializza i primi 6 con i 6 bytes di "pippo".
gli ultimi 4 bytes possono contenere qualsiasi cosa, non vengono toccati!
sembra prorio che gli ultimi 4 bytes vengano azzerati !
Tutto questo thread ha confuso un pochino le idee anche a me ma l'imporante
credo che alla fine tra una cosa e l'altra le cose si siano chiarite ! Ciao e
grazie a tutti ! Dave.

primi 5 con pippo senza '\0' al termine, 
Lo '\0' al termine c'e` sempre quando si tratta di un'inizializzazione
con caratteri contenuti tra doppi apici.  Il motivo e` semplice: in C
non esistono le stringhe, esistono solo delle convenzioni per
implementarle.  La convenzione ASCIIZ e` quella che prevede che, per
"stringa", in C, si intenda una sequenza di caratteri terminante con
uno '\0' e che sia, normalmente, rappresentabile chiusa tra doppi
apici.  Quindi, qualsiasi sequenza racchiusa tra doppi apici e`
sicuramente una stringa (mentre non e` detto che qualsiasi array di
caratteri sia necessariamente una stringa).  Quindi, ogni qual volta
vedi dei caratteri racchiusi tra doppi apici, sai che alla fine c'e`
sempre un '\0', perche` trattasi di una stringa.

 sembra prorio che gli ultimi 4 bytes vengano azzerati !
Si, hai ragione.
Tommy

 Saluti
C:\>iao Angelo
P.S. Le pagine citate sono quelle di "Linguaggio C seconda edizione"
     ISBN 88-7056-443-6. Se hai una versione diversa, ovviamente, i
     numeri di pagina potranno non essere gli stessi.


e' esattamente quello che ha detto Dave
in 
Message-ID: <3E02E6C9...@Dave.it>
C:\>iao Angelo