Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    [Preprocessore C] Wrapper macro

    codice:
    inline int Fileno(FILE* fpStream)
    	{
    	int in;
    	
    	if((in = fileno(fpStream)) < 0)
    	   err_sys("(Module: %s) - ERROR fileno()      failed", gargv[0]);
    	
    	return in;
    	}
    Devo trasformare in macro la funzione sovrastante.
    E' un wrapper di fileno() per controllare il codice di errore comodamente.
    Il mio problema è che "inline" è una richiesta, non un comando, e spesso vedo che i compilatori la ignorano per i motivi più disparati.
    Per tagliare la testa al toro volevo ridefinire tutti i miei wrapper come macro.
    Non riesco però a scrivere l'equivalente codice per il preprocessore.

    Ho provato così:

    codice:
    #define Fileno(fp) \
       {               \
       int iRet;       \
       ((iRet = fileno(fp)) < 0) ? rett : err_sys("(Module: %s) - ERROR fileno() failed", gargv[0]); \
       }
    
    La macro la utilizzerei poi tipo così:
    
    int main()
       {
       FILE* fpProva;
       int ifd = Fileno(fpProva);
    
       // ......
    
       return 0;
       }
    Non funziona e dà un errore compilando con g++ 3.2.
    Mi sta venendo il dubbio che non si possa proprio fare.

    Qualche idea?


  2. #2

    Strano...

    codice:
    #define Fileno(fpStream) (1? 	                        \
    		({                                      \
    		int iRet;                               \
    		if((iRet = fileno(fpStream)) < 0)       \
    			err_quit("(Module: %s) - ERROR fileno() failed\n", gargv[0]); \
    		iRet;					\
    		}):0)
    E' un'ora che ci sto sopra e finalmente ho risolto.
    Io non so cosa ci sia sotto la parola chiave "inline", sta di fatto che la funzione macrata guadagna 5 secondi per ogni migliardo di chiamate.
    La funzione inline va a fare qualche cosa che fa sprecare circa 5 ns a ogni chiamata. Vi metto l'output del tempo di CPU qui sotto.

    Istructions load: 1000000000
    Macros vs Inline
    Getting times...

    Inline: 20.620000
    Macro: 15.620000
    Ho seri dubbi sul funzionamento di inline.
    Boh, può essere che mi sbaglio.

    CIAO !

  3. #3

    Uhmm, che mi venga un colpo

    codice:
    #define MBEGIN (1?({
    #define MEND }):0)
    #define RETURN
    
    #define ciccio(iParam)   	          \
    MBEGIN				          \
    	int a, b;                         \
    	a = 1;                            \
            b = 2;		                  \
    	if((a < iParam)                   \
               puts("Ciao pippo !");          \
            RETURN b;
    MEND
    Ma lol, ho provato e sta roba funziona.
    Sembra che uno riesca a farsi i propri comodi nelle macro come fossero funzioni.
    Wow un nuovo linguaggio di programmazzione, CMACRO++
    Ma dov'è la fregatura?
    Sembra troppo bello.

    CIAO !

  4. #4

    Errore

    Mancava la \ nello script di sopra.
    E' così:

    codice:
    #define BEGIN (1?({
    #define END }):0)
    #define RETURN
    
    #define ciccio(iParam)                    \
    BEGIN                                     \
            int a, b;                         \
            a = 1;                            \
            b = 2;                            \
            if((a < iParam)                   \
               puts("Ciao pippo !");          \
            RETURN b;		          \
    END
    Ho preso altri tempi intanto, guardate qua:

    Istructions load: 100000000
    Macros vs Inline
    Getting times...

    Inline: 2.150000 s
    Macro: 0.220000 s


    :master:


  5. #5

    Ok, nessuno risponde...

    Allora ho scoperto l'acqua calda.

    CIAO !

  6. #6

    Re: Errore

    Originariamente inviato da /* Coder */
    Mancava la \ nello script di sopra.
    E' così:

    codice:
    #define BEGIN (1?({
    #define END }):0)
    #define RETURN
    
    #define ciccio(iParam)                    \
    BEGIN                                     \
            int a, b;                         \
            a = 1;                            \
            b = 2;                            \
            if((a < iParam)                   \
               puts("Ciao pippo !");          \
            RETURN b;		          \
    END
    Ho preso altri tempi intanto, guardate qua:





    :master:

    hai compilato con -O3 ?
    se no, prova a compilarlo con questo flag e rifai i bench

    per le macro guarda qui (contro le macro)
    http://www.parashift.com/c++-faq-lit...s.html#faq-9.5
    http://www.parashift.com/c++-faq-lit....html#faq-38.4
    http://www.parashift.com/c++-faq-lit....html#faq-38.5
    http://www.parashift.com/c++-faq-lit....html#faq-38.6

    a favore delle macro
    http://www.idinews.com/macroPhobe.html
    http://c2.com/cgi/wiki?PreprocessorsAreNotEvil


    la fregatura principale la scoprirai quando dovrai utilizzare il debugger.

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2004
    Messaggi
    26
    vorrei farvi notare...

    le direttive non hanno bisogno di punto e virgola gicche non sono istruzzioni da compilare , bensi è un commando al precompilatore.
    il precompilatore esegue questi, che devono essere scritti su una riga
    infatti se scrivete
    #define x
    y
    quell y è fuori posto vi chiede dunque ; o altro.
    il '\'posto prima di '\n'(nuova_linea) fa "skippare" nella traduzione del precompilatore l'effetto di '\n'.
    provate dunque scrivere '\'' '(spazio)e poi '\n': il raggiro non funzia.
    mi chiedevo '\''\n' == commento di n???
    su C non esiste la scrittura \\ come commento ma le direttive funzionano separate da '\''\n'?

    Cmq una piccolezza: ciascuno usa la sua tecnica,
    io ho deciso e sprono chiunque a seguire il mio esempio a scrivere per esempio tutte le definizioni,costanti e macro in maiuscolo
    quelle globali con la prima lettera in maiuscolo
    le locali in minuscolo...
    UTILITà?

    le inline sono funzioni espanse esattamente come le macro
    ma spesso nel lavoro di espansione di una macro può causare errori di compilazione o peggio errori di Run-time difficili da trovare

    si usa quindi spesso su c++ il tipo inline con la bellezza di eliminare la chiamata a funzione ma la funzione c'è!
    la macro viene completamente sostituita come testo!

    la risoluzione di una inline avvolte è complessa (esempio un ciclo)...

    MACRO vs INLINE:

    #define QUADRATO(x) (x*x)//mettete al posto della x la variabile da elevare al quadrato

    inline float Quadrato(float x){return (x*x);} //notare il return di funzione e ';'

    {
    float a,b;
    int c,d;
    /*...*/
    b= QUADRATO(a); //compilato: b = (a * a) !!! sostituzione per testo
    c= QUADRATO(d); //compilato: b = (a * a) !!! sostituzione per testo
    }
    l'inline ha un funzionamento simile a:
    b = Quadrato(a); //b = { a * a }// in più a se definito intero il compilatore aggiunge un recast o vi fa notare

    differenza : le macro sarebbero inaffidabili ofrono completa ottimizzazione,
    le inline sono complesse da espandere e le ottimizzazioni che offrono variano da compilatore a compilatore...
    forse questo per molti è già chiaro cmq rimane la mia domanda un po stolta visto che '\n' è un solo carattere...
    curioso però...

    #define INVERSO(x) (1/x) //questo è un altro esempio
    //con queste due macro non ho mai avuto problema nemmeno con classi, basti che siano definiti le operazioni (/ e *)...

    aspetto risposte... ciao

  8. #8

    Re: Re: Errore

    Originariamente inviato da internet
    hai compilato con -O3 ?
    se no, prova a compilarlo con questo flag e rifai i bench

    per le macro guarda qui (contro le macro)
    http://www.parashift.com/c++-faq-lit...s.html#faq-9.5
    http://www.parashift.com/c++-faq-lit....html#faq-38.4
    http://www.parashift.com/c++-faq-lit....html#faq-38.5
    http://www.parashift.com/c++-faq-lit....html#faq-38.6

    a favore delle macro
    http://www.idinews.com/macroPhobe.html
    http://c2.com/cgi/wiki?PreprocessorsAreNotEvil


    la fregatura principale la scoprirai quando dovrai utilizzare il debugger.
    Si grazie, mi sono studiato i 4 evil.
    Continuo comunque a preferire le macro, perkè inline non mi da certezze. Cioè se io dico "inline" al compilatore, non deve discutere, deve espandere in linea e basta, ciò non avviene.
    Quando prima esamino bene tutti gli evil cases e cerco di rendere l'uso del mio costrutto privo della maggior parte di preoccupazioni.
    E' chiaro che non riesco comunque a rendere una macro esattamente come una funzione inline in tutti i casi. Però alle funzioni macro uno le potrebbe dare un nome tutto maiuscolo in modo da allertare e far ricordare all'utilizzatore tutti gli evil prima di commettere sciocchezze.
    Cmq così a prima vista penso che i 4 evil si possono risolvere in modo trasparente, quello però dove c'è l'esempio di macro safe e unsafe per ora non mi viene in mente nulla.

    Quanto prima mi vedo ste cose e riuppo il tutto. Occorre stare attenti perkè ste macro sono carogne per i cosiddetti
    "well-hidden-bugs" .

    Per il fatto della debuggabilità penso di risolvere attraverso vie alternative, tanto il debugger io già lo uso poco per il fatto che faccio molto multi-process.

    Grazie comunque dei link, avevo un sacco di fili scollegati in testa, adesso grazie a te circola corrente.

    Ciao !

  9. #9

    Forse ci siamo.

    Questo "dovrebbe" risolvere tutti gli evil in modo trasparente:

    codice:
    #define BEGIN (true?({ 	// Macro functions init syntax
    #define END }):false)	// Macro functions end syntax
    #define RETURN		// Macro functions return
    #define VOID true	// To be used for void returns
    
    #define Fileno(fpStream) 				\										
    BEGIN			 				\																					
    	int iRet;	 				\																			
    	FILE* FpStReAm = fpStream; 			\													
    				   			\																			
    	if((iRet = fileno(FpStReAm)) < 0) 		\ 											
    		err_quit("(Module: %s) - ERROR fileno() failed\n", gargv[0]); \
    		      					\																				
    	RETURN iRet; 					\																		
    END
    Che ne pensate? riuscite a trovare qualche caso unsafe?

    Ecco il nuovo bench senza ottimizzazione:

    Istructions load: 100000000
    Macros vs Inline
    Getting times...

    Inline: 2.040000 s
    Macro: 1.640000 s
    Fatemi sapere !

    CIAO !!

  10. #10

    In definitiva...

    Alla fine la cosa migliore è definirle inline e compilare ottimizzando così:

    g++ -03 -Winline fileName.cpp
    Se il compilatore non intende mettere inlinea una funzione, ci da un warning come per altro mi è già successo.
    In quel caso si trasforma in macro come suddetto.
    I benchmark con l'ottimizzatore a -03 danno gli stessi tempi con una precisione del centesimo di secondo.
    Internet avevi ragione, ora va.


    Conclusione:

    Se non veniamo avvisati dal compialtore tramite -Winline è sempre meglio usare inline al posto di una macro .
    Concordate?
    Sarebbe bello ogni tanto darsi qualche regola fissa in questo mondo così pieno di dubbi e incertezze quale è la programmazione .

    Risolto il dilemma.

    Ciao !

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.