Newsgroup: it.comp.os.linux.development
Titolo: kernel linux e macrodefinizione __syscall_return

salve,
qualcuno mi sa spiegare il motivo/significato della presenza
del do { ...... } while(0) all'interno della macro per la gestione della
syscall return() nel kernel linux?
lo riporto:
in linux/include/asm-i386/unistd.h
#define __syscall_return(type, res) \
do { \
        if ((unsigned long)(res) >= (unsigned long)(-125)) { \
                errno = -(res); \
                res = -1; \
        } \
        return (type) (res); \
} while (0)
grazie in anticipo

 lo riporto:
Se ci fai caso, quello è un ciclo che viene eseguito solo una volta. Il suo
ruolo è quello di fornire un metodo pratico per contenere più righe di
codice di una macro. E' soltanto il metodo più classico adoperato per macro
multilinea. Tutto qui.
Ciau
--
Don't you know why your Python application has crashed?
Take a look to 
http://www.pycrash.org
My Home Page 
http://cnoviello.altervista.org
Sei un programmatore Python? E allora leggi PyJournal.it (
www.pyj.it
)

 macro multilinea. Tutto qui.
ho capito, e' usato, diciamo, come "contenitore".
ecco perche' in altri tipi di macro non viene usato, vedi quelle per la
definizione delle syscall parametriche, li infatti definiscono le funzioni
e le delimitano con le graffe.
grazie mille

 ho capito, e' usato, diciamo, come "contenitore".
E` piu` di un contenitore, serve per evitare brutte sorprese:
#define BAD()   foo(); \
                bar(); \
                quux()
#define GOOD() do {     \
                foo();  \
                bar();  \
                quux(); \
        } while(0)
Se usi la prima macro in ramo if otterrai un risultato diverso da quello
che ti aspetti (o anche un errore di compilazione):
if (blah)
        BAD();
else
        foobar();
viene espanso in:
if (blah)
        foo(); bar(); quux();
else
        foobar();
che evidentemente non puo` compilare. Invece:
if (blah)
        foobar();
else
        BAD();
diventa:
if (blah)
        foobar();
else
        foo(); bar(); quux();
che e` piu` subdolo perche` funziona ma non fa quello che ti
aspetteresti leggendo il codice. do {...} while(0) fa si che tutta la
macro venga vista come un unico statement, evitando tutti questi
problemi.
Luca
-- 
Home: 
http://kronoz.cjb.net
Al termine di un pranzo di nozze mi hanno dato un
amaro alle erbe cosi' schifoso che perfino sull'etichetta
c'era un frate che vomitava.

 Luca
ti ringrazio, mi ero reso comunque conto che lo scopo fosse quello.
Solo un ultima cosa
questo tipo di sintassi e' necessaria per tutti i compilatori c o solo 
per il gcc?

 per il gcc?
Non è un problema di compilatori C in generale o di gcc nello specifico:
quella sintassi è necessaria per aggirare un limite dei preprocessori.
Il preprocessore non agisce a livello "grammaticale", se così si può dire,
ma non fa altro che fare delle macro espansioni. E quindi, non vi è alcun
controllo da parte sua sulla correttezza semantica del codice espanso. Il
preprocessore non effettua una trasformazione del codice (che per
definizione deve essere semanticamente equivalente), ma solo una macro
espasione. Mi spiego meglio. Nell'esempio che ti hanno fatto
precedentemente:
if (blah)
        BAD();
else
        foobar();
Se BAD() fosse una *reale* funzione C, non vi sarebbero problemi di nessun
tipo. Invece, dato che BAD verrà espansa successivamente, e dato che il
preprocessore non tiene minimamente conto della grammatica C, quel che ne
viene fuori è che il preprocessore innavertitamente introduce del codice
sintatticamente non valido (che è il caso migliore).
E' ovvio che questo si deve anche al fatto che il programmatore tende a
dimenticare che il preprocessore è un elemento estraneo al linguaggio, e che
quindi alla fine quello che conta è il codice preprocessato. Quei trucchi
servono appunto ad evitare che una *banale* macro espansione possa
inavvertitamente alterare la semantica introdotta dal programmatore.


 inavvertitamente alterare la semantica introdotta dal programmatore.
ok, ti ringrazio di nuovo, ora ho capito anche perche', per evitare problemi
nei costrutti condizionali, non usano solo le {} per delimitare le macro ma
piuttosto la do{}while(0)

 problemi.
e non sarebbe piu' comodo usare semplicemente le parentesi graffe,
senza scomodare il costrutto do...while ?
In fondo la loro funzione e' proprio questa: raggruppare piu'
istruzioni in un unico statement.
#define BOH() {pippo(); \
               pluto(); \
               paperino();}
-- 
addio, e grazie per tutto il pesce

 piuttosto la do{}while(0)
io invece no!
Ho scritto decine di macro monoblocco, sia di quelle che valgono una
una espressione intera e quindi tra () sia di quelle tra {} e mai
mi e' venuta in mente la perversione di usare un do{ }while() e tuttora
non capisco.
ciao
roberto.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

...

in questo modo questo pezzo di codice darebbe errore (nell'usare il punto e virgola)
if( bleah )
    BOH();
else
    foo();
http://www.kernelnewbies.org/faq/index.php3#dowhile
Ciao
Matic`WinGugol