Newsgroup: it.comp.lang.c++
Titolo: Inline

Chi mi spiega a cosa serve la parola chiave  <  INLINE >  .
Grazie
~Guybrush~

 ~Guybrush~
Serve a far espandere la funzione al preprocessore in modo evitare la 
chiamata alla funzione, dato che è come se venisse sostituito il codice ad 
ogni chiamata.
ciao
-- 
Luigi
bug windows [5] = {"95", "98", "NT", "Me", "2000"};

 ogni chiamata.
l'equivalente di una macro?
es.:
#define MAX(a,b)  ((a>b)?a:b)
ciao
xaero

#define MAX(a,b)  ((a>b)?a:b)
Meglio di una macro :) ... se ad esempio scrivi
  x=MAX(f(),g());
allora se usi una macro la funzione f() oppure la funzione g()
viene chiamata due volte: una volta per fare il test e una
per restituire il valore. Inoltre le macro sono "pericolose"
perche' se scritte distrattamente possono creare problemi...
ad esempio tu non hai fatto attenzione a racchiudere "a" e "b"
sempre fra parentesi e questo potrebbe creare problemi con la
precedenza degli operatori < e ?: ed eventuali espressioni che
siano passate come argomenti a MAX.
Una funzione inline scritta ad esempio come
   inline int MAX(int a,int b) { return a>b ? a : b; }
non soffre del problema della doppia chiamata a funzione e
nemmeno di quello della precedenza nell'ordine di valutazioni
espressioni essendo, da un punto di vista semantico,
equivalente a una funzione "normale".
Per ottenere quasi lo stesso grado di flessibilita' della
macro sul tipo di dato passato e' anche possibile scrivere
un template MAX parametrizzato sul tipo:
  template<class T>
  inline T MAX(const T& a,const T& b)
  { return a>b ? a : b; }
(Ho detto quasi perche' una macro accetta anche cose come
MAX(3.4,12) mentre questo template non l'accetterebbe
richiedendo che il tipo dei due parametri sia identico:
MAX(int,int) e MAX(double,double) sono ok... MAX(int,double)
non e' compatibile con il template nonostante sia possibile
convertire implicitamente un int in un double).
Aggiungo solo che, diversamente da una macro, la parola "inline"
e' solo un *consiglio* dato al compilatore che e' libero di fare
quello che gli pare al riguardo. In effetti questo tipo di
ottimizzazione e' presente solo perche' i compilatori non sono
abbastanza furbi da capire da soli cosa conviene dichiarare
inline e cosa no (in realta' alcuni compilatori C/C++ gia'
prendono da soli decisioni di questo tipo).
Quando i compilatori avranno raggiunto un livello sufficiente di
intelligenza (e i computer un livello sufficiente di potenza)
la parola "inline" sara' tanto inutile quanto la "register" che
gia' oggi e' praticamente ignorata dalla maggior parte dei
compilatori.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

#define MAX(a,b)  ((a>b)?a:b)
No. 
Piu' sicura.

 ogni chiamata.
No. Il preprocessore gestisce le macro. Inline non ha nulla a che vedere con il
preprocessore.
Inline e' un "hint". Ovvero un suggerimento per il generatore di codice e per
l'ottimizzatore. Lo scopo e' di identificare una funzione come candidata per
l'espansione inline (invece che una chiamata) in quanto e' molto breve (il tempo
necessario alla chiamata e' proporzionalmente grosso rispetto al tempo di
esecuzione del codice e la dimensione del codice che esegue la chiamata e'
maggiore o uguale al codice interno alla funzione stessa) o fatta in modo tale
da rendere molto probabile che l'espansione inline possa portare a ulteriori
ottimizzazioni nel codice chiamante.
Un compilatore non e' obbligato a espandere inline una funzione dichiarata
inline. Ad un compilatore non e' vietato espandere inline una funzione che non
e' dichiarata inline.
Un buon compilatore non espanderà inline nessuna funzione quando compila in
modalità debug, indipendentemnete dalla keyword inline. Un buon compilatore
espanderà inline tutte e solo le funzioni per cui l'espansione risulta
conveniente rispetto ai paramentri di ottimizzazione impostati quando compila in
modalità release, indipendentemnete dalla keyword inline.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

modalità release, indipendentemnete dalla keyword inline.
Quindi con un bun compilatore potrei non usare mai inline, senza
preoccuparmi, intanto ci penserà lui?
Ciao
Marco Barisione (ICQ 84277092)

 wrote in message
news:3ae87131...@news.inwind.it...

Esatto. Per esempio in VC7 puoi controllare via switch il comportamento.
1) niente e' mai inline.
2) inline dove tu hai scritto inline (se possibile)
3) inline tutto quello che ha senso rendere inline.
Se poi abiliti anche gli switch di ottimizzazione globale ... potresti stupirti
di cosa diventa inline e di come questo inline venga ottimizzato!
Per esempio mettendo questo codice in un file:
int triangle( int x )
{
    int result = 0;
    for (int i = 1; i <= x; ++i)
        result += i;
    return result;
}
e questo in UN ALTRO FILE:
int triangle( int x );
int loop()
{
    int sum=0;
    for (int i = 0; i != 9000000; ++i)
        sum += triangle( 10 );
    return sum;
}
e compilando con il massimo delle ottimizzazioni, questo e' il disassemblato
della funzione loop:
PUBLIC ?loop@@YIHXZ     ; loop
; Function compile flags: /Ogty
; COMDAT ?loop@@YIHXZ
_TEXT SEGMENT
?loop@@YIHXZ PROC NEAR     ; loop, COMDAT
    mov eax, 495000000    ; 1d8119c0H
    ret 0
?loop@@YIHXZ ENDP     ; loop
END
Non male!


preoccuparmi, intanto ci penserà lui?
Non credo esistino ancora compilatori cosi' "intelligenti".

ogni chiamata.
no. Sono espanse dal *compilatore* non dal preprocessore. Per
ulteriori informazioni vedi il post di Andrea
Anto
--
Antonio Cuni, 18 anni, studente
Brainbench Certification: 
Master C++: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
http://www.brainbench.com/transcript.jsp?pid=1301688

Esatto. Per esempio in VC7 puoi controllare via switch il comportamento.
però perdi di portabilità. Molto meglio specificarlo




Io ricordo di aver visto fare cose del genere al Watcom 9.xx con
i programmi C (funzioni normalissime che venivano incorporate e
semplificate con il codice nel punto di chiamata)


 però perdi di portabilità. Molto meglio specificarlo
Parlando di ottimizzazione la portabilità e' un controsenso! Che cosa stai
"portando"? Il tempo di esecuzione?
Ha senso rendere inline quelle funzioni per le quali e' assolutamente evidente
che l'implementazione inline e' la piu' ovvia. E sperare che anche il piu'
pessimo dei compilatori sia in grado di farlo.
Per esempio:
class A
{
    int i;
public:
    int getI() const { return i; }
};
mettere l'implementazione di getI in un file separato sperando che il
compilatore possa ottimizzare anche fra unità di compilazione diverse e' una
pessima idea.
Ma molto piu' in la di questo io non andrei con la convenienza di rendere tutto
inline.


 wrote in message
news:3ae93189...@news.libero.it...

VC lo e' da un pezzo per quanto riguarda il codice visibile nella translation
unit.
VC7 lo e' anche su translation unit distinte.


"portando"? Il tempo di esecuzione?
non il tempo di esecuizione, ma, se mi consentite di coniare un
termine, la "convenienza di utilizzo"; mi spiego: se io faccio un
wrapper mi aspetto che non comporti costi a runtime; ma se non
specifico inline (o se non lascio i metodi all'interno della
definizione di classe) non posso essere *ragionevolmente* sicuro che
il wrapper sia sempre efficiente in un futuro porting (la sicurezza
matematica non la avrò mai, ma una "statistica" si).
Ho già trovato alcune volte il termine "portabile" utilizzato in un
contesto un po' insolito; tanto per fare un esempio sullo Stroustrup
c'è scritto che rand()%n non è un metodo portabile per generare num
casuali.


 casuali.
Non so cosa intenda BS, ma certo so che non e' neppure un metodo per generare
numeri casuali. Indipendentemente dalla portabilità! Vedi altro thread.


 ~Guybrush~
---------------------------------
E' una tecnica utilizzata per aumentare la velocità di un programma. Quando
si rende Inline una funzione, il corpo della funzione viene copiato
direttamente nel codice sorgente e dunque in realtà non verrà richiamata
nessuna funzione.

numeri casuali. Indipendentemente dalla portabilità! Vedi altro thread.
metti un 
#define casuali pseudo-casuali
prima del mio post.
E cmq Stroustrup intendeva che usando il modulo non è sicuro che si
ottenga una sequenza pseudo-casuale, visti i generatori solitamente
usati. Quindi rand()%n non sempre genererà una sequenza di numeri
pseudo-casuali, perciò non è portabile.


 matematica non la avrò mai, ma una "statistica" si).
Anche questa e' un'illusione: se l'incremento della dimensione del
codice fa "straripare" il medesimo dalla cache, potresti avere un
peggioramento di prestazioni piu' ingente che non lasciando la chiamata
fuori linea.
Ciao,
Nicola