Come dice il titolo; qual è la differenza nella pratica tra la parola chiave inline e la direttiva #define del preprocessore?Qual è la differenza nella pratica tra inline e #define?
risposta
#define
è uno strumento preprocessore e ha la semantica macro. Considerate questo, se max(a,b)
è una macro definita come
#define max(a,b) ((a)>(b)?(a):(b))
:
Ex 1:
val = max(100, GetBloodSample(BS_LDL))
sarebbe versare sangue in più innocente, perché la funzione sarà effettivamente chiamato due volte. Ciò potrebbe significare una significativa differenza di prestazioni per le applicazioni reali.
Es 2:
val = max(3, schroedingerCat.GetNumPaws())
Questo dimostra un grave differenza nella logica del programma, perché questo può restituire inaspettatamente un numero che è inferiore a 3 - qualcosa che l'utente non ci si aspetterebbe.
Ex 3:
val = max(x, y++)
potrebbe incrementare più di una volta y
.
Con funzioni in linea, nessuna di queste accadrà.
Il motivo principale è che il concetto di macro obiettivi la trasparenza di attuazione (codice testuale sostituire) e gli obiettivi in linea concetti linguaggio corretto, rendendo la semantica invocazione più trasparente per l'utente.
+1 Per l'esempio di spargimento di sangue – Tomas
È necessario modificare 'shroedingerCat.GetNumPaws()' per essere una funzione C, non C++. – alternative
Bene, la domanda riguarda C; è però più comune per le funzioni dei membri C++ restituire di volta in volta cose diverse, perché si basano naturalmente sullo stato del loro oggetto. –
La differenza è descritta abbastanza in modo approfondito qui: http://www.geekinterview.com/question_details/23831 applausi
macro (creati con #define
) sono sempre sostituiti come scritto, e possono avere problemi di doppia valutazione.
inline
d'altra parte, è puramente consultivo - il compilatore è libero di ignorarlo. Sotto lo standard C99, una funzione inline
può anche avere linkage esterno, creando una definizione di funzione che può essere collegata contro.
Beh, un multi-linea di #define
è più difficile da scrivere e modificare di una funzione inline. È possibile definire una funzione in linea come qualsiasi funzione normale e definire variabili senza problemi. Immagina di voler chiamare un blocco di codice più volte all'interno di un'altra funzione e che il blocco di codice ha bisogno di variabili proprie: è più facile da fare con le funzioni inline (sì, puoi farlo con #defines e do { ... } while (0);
ma è qualcosa che devi Pensa a).
Inoltre, con abilitato il debug, normalmente si ottiene un "simulato" stack-frame per funzioni inline che potrebbe rendere più facile il debug a volte (almeno questo è quello che si ottiene quando si compila/link con gcc di -g
e debug con GDB, IIRC). È possibile posizionare punti di interruzione all'interno della funzione inline.
parte che il risultato dovrebbe essere quasi identico, AFAIK.
Le macro di tipo funzione forniscono un controllo di integrità assolutamente zero nel punto in cui sono definite.Quando fai una cacca con una macro, funzionerà bene in un punto e sarà rotta da qualche altra parte, e non saprai perché fino a quando non avrai perso molte ore di lavoro/tempo di sonno. Le macro di tipo funzione non operano sui dati, operano su codice sorgente. A volte questo è buono, per esempio quando si vogliono istruzioni di debug riutilizzabili che usano i compilatori e LINE, ma la maggior parte delle volte può essere eseguito altrettanto bene con una funzione inline, che viene controllata per la sintassi al punto di definizione proprio come qualsiasi altra funzione.
Funzioni (sia inline
o meno) e macro soddisfano diversi scopi. La loro differenza non dovrebbe essere vista come ideologica come alcuni sembrano prenderla, e ciò che è ancora più importante, possono funzionare bene insieme.
macro sono la sostituzione del testo che viene fatto al momento della compilazione e possono fare cose come
#define P99_ISSIGNED(T) ((T)-1 < (T)0)
che ti dà un'espressione fase di compilazione o meno un tipo integrale è firmato o meno. Cioè, sono idealmente utilizzati quando il tipo di un'espressione non è noto (alla definizione) e si vuole fare qualcosa al riguardo. D'altra parte, il trabocchetto con le macro è che i loro argomenti possono essere valutati più volte, il che è negativo a causa degli effetti collaterali.
Le funzioni (inline
) sull'altro sono digitate, il che le rende più rigide o, formulate in modo negativo, meno flessibili. Considerare le funzioni
inline uintmax_t absU(uintmax_t a) { return a; }
inline uintmax_t absS(uintmax_t a) {
return (-a < a) ? -a : a;
}
Il primo implementa la funzione abs
banale per un tipo intero senza segno. Il secondo lo implementa per un tipo firmato. (sì, ci vuole un argomento senza segno, questo è per scopo.)
Possiamo usarli con qualsiasi tipo di integrale. Ma il tipo di ritorno sarà sempre della larghezza maggiore e c'è una certa difficoltà nel sapere come scegliere tra i due.
Ora, con la seguente macro
#define ABS(T, A) ((T)(P99_ISSIGNED(T) ? absS : absU)(A))
abbiamo implementato una famiglia
- di funzioni
- che funziona per qualsiasi tipo integrale
- che valuta il suo argomento solo una volta
- per il quale verrà creato un compilatore recente e rispettabile Codice ottimale
- 1. Differenza tra #Define e Float?
- 2. Qual è la differenza tra http e https nella programmazione
- 3. Qual è la differenza tra dict() e {}?
- 4. Qual è la differenza pratica tra la finestra di comando e la finestra immediata?
- 5. Qual è la differenza tra = e: =
- 6. Qual è la differenza tra Verilog! e ~?
- 7. Qual è la differenza tra? : e ||
- 8. qual è la differenza tra [[], []] e [[]] * 2
- 9. Qual è la differenza tra $ e $$?
- 10. Qual è la differenza tra ("") e (null)
- 11. Qual è la differenza tra " " e ""?
- 12. Qual è la differenza tra {0} e ""?
- 13. Qual è la differenza tra `##` e `hashCode`?
- 14. Qual è la differenza tra {0} e +?
- 15. Qual è la differenza tra .ToString() e + ""
- 16. qual è la differenza tra:.! e: r !?
- 17. Qual è la differenza tra assert e static_assert?
- 18. Differenza tra una funzione inline e una funzione inline statica
- 19. Qual è la differenza tra le variabili globali e # define in c
- 20. Qual è la differenza pratica tra data.frame e data.table in R
- 21. Differenza pratica tra Elenco e IEnumerable
- 22. Qual è la differenza tra definire e richiedere in RequireJS?
- 23. Qual è la differenza tra "WCHAR" e "wchar_t"?
- 24. Javascript - inline vs script esterno - qual è la differenza?
- 25. Qual è la differenza tra stdin e STDIN_FILENO?
- 26. Qual è la differenza tra SortedList e SortedDictionary?
- 27. Qual è la differenza tra QCheckBox :: commutato() e QCheckBox :: cliccato()?
- 28. Qual è la differenza tra queste funzioni
- 29. Qual è una differenza pratica tra un loop e la ricorsione
- 30. Qual è la differenza pratica tra i registri SI e DI?
possibile duplicato del [funzioni inline vs preprocessore macro] (http (Beh, ammetto che fare questo con
abs
è un po 'artificiale, ma spero che si ottiene l'immagine.): // stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros) – jww