Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157

    [C++] Differenza "inline" e "#define" e analisi codice

    Buonasera, avrei gentilmente bisogno di un vostro aiuto.

    Sbirciando dei codici c++ trovati su internet per imparare, mi sono imbattuto in alcuni problemi. Ve li espongo:

    1. Qual'è la differenza tra "inline" e "#define"?

    Questo è un esempio in cui la medesima funzione restituisce valori diversi a seconda se essa è definita con inline o con #define:

    codice:
    #define SQUARE(x) ((x)*(x))
    int a = 2;
    int b = SQUARE(a++);
    
    // Alla fine risulta a = 4, b = 2*3 = 6
    codice:
    inline int SQUARE(int x)
    {
       return x*x;
    }
    int a = 2;
    int b = SQUARE(a++);
    
    // Alla fine risulta a = 2, b = 2*2 = 4
    Perché i due codici si comportano in maniera differente? Cosa succede precisamente? Ho sentito che inline serve per ridurre il tempo di overhead... è quindi consigliabile usare SEMPRE inline al posto di define oppure di non utilizzare niente?

    2. Ho trovato il seguente codice:

    codice:
    #ifndef NO_ASSERTD
    #undef  assertd
    #define assertd(exp) ((void)NULL)
    #endif
    
    ...
    
    inline char GetAt(int pos) const 
    {
       assertd(pos<Len); return pData[pos]; 
    }
    Quello che mi chiedo è: assertd è una funzione standard del C/C++ che voi sappiate? NULL è una costante predefinita in C++? Si può scrivere NULL in minuscolo? Cosa significa (exp)((void)NULL)?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    L'inline non c'entra nulla ... il problema e' quel

    a++

    che usato con la define, viene tradotto

    ((a++)*(a++))


    Capito il problema?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da oregon
    L'inline non c'entra nulla ... il problema e' quel

    a++

    che usato con la define, viene tradotto

    ((a++)*(a++))


    Capito il problema?
    Grazie per avermi risposto, ma purtroppo non ho capito. Anch'io ho pensato subito ad (a++)*(a++), e poiché
    a = 2, a++ = 3 quindi risulterebbe b = 9... invece dà 6 con define e 4 con inline... perché?

    A che serve "inline" allora?

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Originariamente inviato da xshell
    Grazie per avermi risposto, ma purtroppo non ho capito. Anch'io ho pensato subito ad (a++)*(a++), e poiché
    a = 2, a++ = 3 quindi risulterebbe b = 9... invece dà 6 con define e 4 con inline... perché?
    Con la define la riga
    codice:
    SQUARE(a++)
    viene tradotta in
    codice:
    ((a++)*(a++))
    ; questa espressione viene valutata in questa maniera (scrivo a sinistra il valore di a nel passaggio in questione e a destra lo "stato" dell'espressione):
    codice:
    a=2        ((a++)*(a++))
    --- valuto il primo a++ ---
    a=3        ((2)*(a++))
    --- valuto il secondo a++ ---
    a=4        ((2)*(3))
    --- valuto l'espressione risultante ---
    a=4        6
    ne deriva che al termine della valutazione a varrà 4 e il risultato finale sarà 6. Nel caso della funzione square, invece il valore di a viene passato alla funzione SQUARE, e solo dopo viene incrementato. Di conseguenza a al termine dell'elaborazione varrà 3, e il risultato sarà 4.
    Ricorda: le macro effettuano una sostituzione di testo "stupida", per cui gli argomenti passati se compaiono più volte nella definizione della macro vengono valutati più volte (e se la valutazione di tali argomenti ha degli effetti secondari questi si verificano più volte), le funzioni inline invece si comportano esattamente come funzioni normali.
    A che serve "inline" allora?
    Serve a consigliare al compilatore di effettuare l'inlining della funzione, ossia di piazzare il suo codice macchina direttamente nel flusso di codice corrente senza stare a creare una funzione separata da chiamare con l'istruzione assembly CALL, evitando così l'overhead che si genera per ogni chiamata a funzione. Di fatto l'inlining viene impiegato spesso per funzioni brevi, mentre per funzioni più lunghe si utilizza la normale chiamata a funzione per evitare di ingigantire inutilmente l'eseguibile finale.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da shodan
    Leggi qui.
    http://www.umbertosorbo.it/wiki/inde...unzioni_inline
    Grazie mille, molto interessante. L'ho inserito tra i preferiti: domani lo leggerò con più attenzione e tranquillità.

    Originariamente inviato da MItaly
    Serve a consigliare al compilatore di effettuare l'inlining della funzione, ossia di piazzare il suo codice macchina direttamente nel flusso di codice corrente senza stare a creare una funzione separata da chiamare con l'istruzione assembly CALL, evitando così l'overhead che si genera per ogni chiamata a funzione. Di fatto l'inlining viene impiegato spesso per funzioni brevi, mentre per funzioni più lunghe si utilizza la normale chiamata a funzione per evitare di ingigantire inutilmente l'eseguibile finale.
    Quindi inline ha l'effetto di velocizzare l'esecuzione ma ingigantire l'eseguibile, mentre se non si utilizzasse inline, il programma sarebbe meno veloce ma più leggero, giusto?

    Originariamente inviato da MItaly
    codice:
    a=2        ((a++)*(a++))
    --- valuto il primo a++ ---
    a=3        ((2)*(a++))
    --- valuto il secondo a++ ---
    a=4        ((2)*(3))
    --- valuto l'espressione risultante ---
    a=4        6
    Dopo un po' di tempo a pensarci su, credo di aver finalmente capito. Un po' laborioso il ragionamento, a causa di quei ++, ma alla fine ho compreso. Grazie.

    Un'ultima cosa: esaminando il codice sorgente di Blender, il programma di modellazione opensource, per pura curiosità, ho trovato le righe di codice che ho postato sopra... (ext)((void)NULL) a cosa serve?

  7. #7
    Utente di HTML.it L'avatar di KrOW
    Registrato dal
    Feb 2009
    Messaggi
    281
    Ciao . . . A intuizione è un istruzione simile alla macro assert (documentati sul funzionamento di quest ultima) . . . In pratica se NO_ASSERTD è definito, viene ridefinita la macro assertd in modo che non faccia niente (istruzione (void)NULL ) . . . E' importante capire che (void)NULL è necessaria affinchè un istruzione tipo :
    codice:
    assertd(i==0);
    Venga espansa in :
    codice:
    (void)NULL;
    Nota che se assertd fosse ridefinita così:
    codice:
    #define assertd(exp)
    L' istruzione
    codice:
    assertd(i==0);
    uerrebbe espansa in:
    codice:
    ;
    Il che è un errore . . .
    C++ 4ever
    496e2062696e6172696f206e6f6e2063692061767265737469 206e656d6d656e6f2020726f7661746f203a29

  8. #8
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da KrOW
    Ciao... A intuizione è un istruzione simile alla macro assert (documentati sul funzionamento di quest ultima)...
    Se fosse simile alla macro ASSERT, allora dovrebbe servire per rintracciare errori del codice, fornendo ulteriori informazioni per il debug, ma ho cercato ASSERTD è non è uscito niente... sai dove posso trovare le macro predefinite da utilizzare in C++? Ad esempio sò che alcune macro servono per eseguire alcune determinate linee di codice in base al sistema operativo su cui si fa girare l'eseguibile... e ci sono molte altre macro molto utili che desidererei conoscere... però non sò assolutamente dove trovarle (perché ovviamente i libri spiegano solo i concetti, non forniscono l'elenco di tutte le macro e funzioni... altrimenti servirebbe una enciclopedia intera di C++).

    Originariamente inviato da KrOW
    E' importante capire che (void)NULL è necessaria affinchè un istruzione tipo:
    codice:
    assertd(i==0);
    Venga espansa in:
    codice:
    (void)NULL;
    Nota che se assertd fosse ridefinita così:
    codice:
    #define assertd(exp)
    L'istruzione
    codice:
    assertd(i==0);
    verrebbe espansa in:
    codice:
    ;
    Il che è un errore...
    Quest'ultima parte non l'ho afferrata... potresti spiegarmi meglio?

    exp() non è una funzione matematica? Eppure di matematico nel codice non c'è niente... alla fine (dopo circa un centinaio di righe), il codice dovrebbe generare una libreria per la gestione delle stringhe in Python, per Blender.

    Grazie infinite a tutti per la disponibilità.

  9. #9
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    cerca sull'msdn on-line.. lì c'è tutto ciò che ti serve sul c++

  10. #10
    Utente di HTML.it L'avatar di xshell
    Registrato dal
    Apr 2008
    Messaggi
    157
    Originariamente inviato da Stoicenko
    cerca sull'msdn on-line.. lì c'è tutto ciò che ti serve sul c++
    Ok, proverò. Grazie del consiglio. Dato che MSDN è gigantesco, mi sapresti dire in che sezione cercare? Visual C++ sotto la voce "Developer Tools & Languages"? Oppure su MSDN Library?

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.