Quando devo scrivere la parola chiave "inline" per una funzione / metodo?


562

Quando devo scrivere la parola chiave inlineper una funzione / metodo in C ++?

Dopo aver visto alcune risposte, alcune domande correlate:

  • Quando non dovrei scrivere la parola chiave "inline" per una funzione / metodo in C ++?

  • Quando il compilatore non saprà quando rendere "inline" una funzione / metodo?

  • Importa se un'applicazione è multithread quando si scrive "inline" per una funzione / metodo?


40
Se si definisce una funzione in un'intestazione, sarà necessario dichiararla in linea. Altrimenti otterrai errori del linker su più definizioni della funzione.
Martin York,

15
@Martin: A meno che non sia nella definizione di una classe, essere pignoli.
David Thornley,

20
@ David: Per essere più esigenti, questo è solo perché tali funzioni sono implicitamente contrassegnate inline(9.3 / 2).
Corse di leggerezza in orbita


Vedi anche Funzioni incorporate nelle FAQ di C ++. Hanno un ottimo trattamento dell'inline.
jww

Risposte:


882

Oh amico, uno dei miei animali domestici.

inlineè più simile statico externdi una direttiva che dice al compilatore di incorporare le tue funzioni. extern, static, inlineSono direttive linkage, utilizzati quasi esclusivamente dal linker, non il compilatore.

Si dice che inlinesuggerisce al compilatore che si ritiene che la funzione debba essere integrata. Questo potrebbe essere vero nel 1998, ma un decennio dopo il compilatore non ha bisogno di tali suggerimenti. Per non parlare degli umani di solito hanno torto quando si tratta di ottimizzare il codice, quindi la maggior parte dei compilatori ignora il "suggerimento".

  • static- il nome della variabile / funzione non può essere utilizzato in altre unità di traduzione. Linker deve assicurarsi che non usi accidentalmente una variabile / funzione definita staticamente da un'altra unità di traduzione.

  • extern- usa questo nome variabile / funzione in questa unità di traduzione ma non lamentarti se non è definito. Il linker lo risolverà e si assicurerà che tutto il codice che ha tentato di usare un simbolo esterno abbia il suo indirizzo.

  • inline- questa funzione sarà definita in più unità di traduzione, non ti preoccupare. Il linker deve assicurarsi che tutte le unità di traduzione utilizzino una singola istanza della variabile / funzione.

Nota: in generale, dichiarare i modelli inlineè inutile, poiché hanno già la semantica del collegamento inline. Tuttavia, è necessarioinline utilizzare la specializzazione esplicita e la creazione di istanze di modelli .


Risposte specifiche alle tue domande:

  • Quando devo scrivere la parola chiave "inline" per una funzione / metodo in C ++?

    Solo quando si desidera che la funzione sia definita in un'intestazione. Più esattamente solo quando la definizione della funzione può essere visualizzata in più unità di traduzione. È una buona idea definire piccole funzioni (come in una riga) nel file di intestazione in quanto fornisce al compilatore ulteriori informazioni su cui lavorare mentre ottimizza il codice. Aumenta anche il tempo di compilazione.

  • Quando non dovrei scrivere la parola chiave "inline" per una funzione / metodo in C ++?

    Non aggiungere in linea solo perché pensi che il tuo codice verrà eseguito più velocemente se il compilatore lo incorpora.

  • Quando il compilatore non saprà quando rendere "inline" una funzione / metodo?

    Generalmente, il compilatore sarà in grado di farlo meglio di te. Tuttavia, il compilatore non ha l'opzione per incorporare il codice se non ha la definizione della funzione. Nel codice ottimizzato al massimo di solito tutti i privatemetodi sono indicati se lo chiedi o meno.

    A parte questo, per evitare di entrare in GCC, usa __attribute__(( noinline )), e in Visual Studio, usa __declspec(noinline).

  • Importa se un'applicazione è multithread quando si scrive "inline" per una funzione / metodo?

    Il multithreading non influisce in alcun modo sull'inline.


172
+1 Migliore descrizione di inline che ho visto in ... (per sempre). Ora ti strapperò e lo userò in tutte le mie spiegazioni della parola chiave incorporata.
Martin York,

6
@Ziggy, quello che stavo cercando di dire era che la compilazione del compilatore e la inlineparola chiave non sono correlate. Hai l'idea giusta però. Di norma, indovinare cosa sarebbe migliorato dall'allineamento è molto soggetto a errori. L'eccezione a quella regola è una fodera.
deft_code

4
Questa risposta mi confonde un po '. Dici tutto sul fatto che il compilatore sia in grado di incorporare / non meglio le cose. Quindi dici che dovresti inserire una linea / piccole funzioni nell'intestazione e che il compilatore non può incorporare il codice senza la definizione della funzione. Non sono un po 'contraddittorie? Perché non mettere tutto nel file cpp e lasciare che il compilatore decida?
user673679,

5
Il compilatore incorporerà solo le chiamate di funzione in cui la definizione è disponibile nel sito di chiamata. Lasciare tutte le funzioni nel file cpp limiterebbe l'allineamento a quel file. Suggerisco di definire le piccole linee di linea in linea in .h poiché il costo per la velocità di compilazione è trascurabile e sei quasi sicuro che il compilatore inserirà la chiamata. Il mio punto sull'allineamento del compilatore è che è la porta dell'arte nera dell'ottimizzazione, in cui il tuo compilatore è molto meglio di te.
deft_code

8
Ogni volta che leggo qualcosa sul conto della conoscenza cumulativa di Internet, devo pensare alla famosa citazione di John Lawton: L'ironia dell'era dell'informazione è che ha dato nuova rispettabilità all'opinione non informata.
Indispensabile l'

60

Vorrei contribuire a tutte le grandi risposte in questa discussione con un esempio convincente per dissipare eventuali equivoci rimanenti.

Dati due file di origine, come ad esempio:

  • inline111.cpp:

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
  • inline222.cpp:

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }

  • Caso A:

    Compilare :

    g++ -std=c++11 inline111.cpp inline222.cpp

    Uscita :

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0

    Discussione :

    1. Anche se dovresti avere definizioni identiche delle tue funzioni inline, il compilatore C ++ non lo contrassegna in caso contrario (in realtà, a causa della compilazione separata non ha modo di controllarlo). È tuo dovere assicurarti questo!

    2. Linker non si lamenta di One Definition Rule , come fun()dichiarato inline. Tuttavia, poiché inline111.cpp è la prima unità di traduzione (che in realtà chiama fun()) elaborata dal compilatore, il compilatore crea un'istanza fun()al suo primo incontro di chiamata in inline111.cpp . Se il compilatore decide di non espandere fun()la propria chiamata da qualsiasi altra parte del programma ( ad es. Da inline222.cpp ), la chiamata a fun()sarà sempre collegata alla sua istanza prodotta da inline111.cpp (la chiamata fun()all'interno di inline222.cpppuò anche produrre un'istanza in quell'unità di traduzione, ma rimarrà non collegata). In effetti, ciò è evidente dalle &fun = 0x4029a0stampe identiche .

    3. Infine, nonostante il inlinesuggerimento al compilatore di espandere effettivamente il one-liner fun(), ignora completamente il tuo suggerimento, il che è chiaro perché fun() = 111in entrambe le righe.


  • Caso B:

    Compila (nota ordine inverso) :

    g++ -std=c++11 inline222.cpp inline111.cpp

    Uscita :

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980

    Discussione :

    1. Questo caso afferma ciò che è stato discusso in caso A .

    2. Si noti un punto importante, che se si commenta la chiamata effettiva fun()in inline222.cpp ( ad es. Commento di coutoutstatement in inline222.cpp completamente), quindi, nonostante l'ordine di compilazione delle unità di traduzione, fun()verrà istanziato al primo incontro di chiamata in inline111.cpp , con conseguente stampa per il caso B come inline111: fun() = 111, &fun = 0x402980.


  • Caso C:

    Compila (avviso -O2) :

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp

    o

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp

    Uscita :

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900

    Discussione :

    1. Come descritto qui , l' -O2ottimizzazione incoraggia il compilatore ad espandere effettivamente le funzioni che possono essere integrate (si noti anche che -fno-inlineè predefinito senza opzioni di ottimizzazione). Come è evidente dalla stampa qui, il file fun()è stato effettivamente ampliato in linea (secondo la sua definizione in quella particolare unità di traduzione), risultando in due stampe diverse fun() . Ciononostante, esiste ancora solo un'istanza collegata a livello globale di fun()(come richiesto dallo standard), come risulta dalla stampa identica &fun .

8
La tua risposta è un post illustrativo del perché il linguaggio rende tali inlinefunzioni un comportamento indefinito.
R Sahu,

Dovresti anche aggiungere casi in cui la compilazione e il collegamento sono separati, ognuno dei .cppquali è la propria unità di traduzione. Preferibilmente, aggiungere casi per -fltoabilitato / disabilitato.
Syockit,

Il riferimento C ++ dice esplicitamente "Se una funzione inline o una variabile (dal C ++ 17) con collegamento esterno è definita in modo diverso nelle diverse unità di traduzione, il comportamento non è definito.". Quindi le cose che hai scritto sono specifiche di GCC in quanto sono un effetto collaterale dell'orchestrazione dei processi di compilazione e collegamento. Si noti inoltre che ciò può variare tra le versioni.
Petr Fiedler

27

Devi ancora incorporare esplicitamente la tua funzione quando esegui la specializzazione del modello (se la specializzazione è nel file .h)


21

1) Al giorno d'oggi, praticamente mai. Se è una buona idea incorporare una funzione, il compilatore lo farà senza il tuo aiuto.

2) Sempre. Vedi # 1.

(Modificato per riflettere che hai diviso la tua domanda in due domande ...)


Sì. Inline è solo un suggerimento per il compilatore ed è libero di ignorarti. In questi giorni il compilatore probabilmente conosce meglio del programmatore quali funzioni sono meglio incorporare.
Mark Byers,

1
Sì, ma è meno rilevante: affinché una funzione sia incorporata, il suo corpo deve trovarsi nella stessa unità di compilazione (ad esempio, in un'intestazione). Questo è meno comune nei programmi C.
Michael Kohne,

1
la definizione di un modello di funzione non membro (noto anche come modello di funzione non statico) non richiede in linea. Vedi una regola di definizione (3.2 / 5).
deft_code

2
-1: inlineè ancora necessario, ad esempio per definire una funzione in un file di intestazione (e ciò è necessario per incorporare tale funzione in più unità di compilazione).
Melebio

1
@ Étienne che è specifico per l'implementazione. Per standard, c'è una regola di definizione, che significa che se includi ingenuamente la definizione di funzione in più unità di traduzione, otterrai un errore. Ma se quella funzione ha un inlineidentificatore, le sue istanze vengono automaticamente compresse in uno dal linker e ODR non viene utilizzato.
Ruslan,

12

Quando non dovrei scrivere la parola chiave "inline" per una funzione / metodo in C ++?

Se la funzione è dichiarata nell'intestazione e definito nel .cppfile, è necessario non scrivere la parola chiave.

Quando il compilatore non saprà quando rendere "inline" una funzione / metodo?

Non esiste una situazione del genere. Il compilatore non può rendere inline una funzione. Tutto ciò che può fare è incorporare alcune o tutte le chiamate alla funzione. Non può farlo se non ha il codice della funzione (in tal caso il linker deve farlo se è in grado di farlo).

Importa se un'applicazione è multithread quando si scrive "inline" per una funzione / metodo?

No, non importa affatto.


Ci sono casi in cui è appropriato usare inline in un file .cpp. Ad esempio, applicare ottimizzazioni al codice che è interamente specifico dell'implementazione.
Robin Davies il

@RobinDavies risposta aggiornata. Sembra che tu abbia frainteso quello che volevo scrivere.
Johannes Schaub - litb

5
  • Quando il compilatore non saprà quando rendere "inline" una funzione / metodo?

Questo dipende dal compilatore utilizzato. Non fidarti ciecamente che al giorno d'oggi i compilatori conoscano meglio gli umani come inline e non dovresti mai usarlo per motivi di prestazioni, perché è la direttiva sul collegamento piuttosto che un suggerimento per l'ottimizzazione. Mentre sono d'accordo sul fatto che ideologicamente sono questi argomenti, l'incontro corretto con la realtà potrebbe essere una cosa diversa.

Dopo aver letto più thread in giro, ho provato per curiosità gli effetti dell'inline sul codice che sto solo lavorando e i risultati sono stati che ho ottenuto una velocità misurabile per GCC e nessuna velocità per il compilatore Intel.

(Maggiori dettagli: simulazioni matematiche con poche funzioni critiche definite al di fuori della classe, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc -O3); l'aggiunta in linea ai punti critici ha causato uno speedup del 6% con il codice GCC).

Quindi, se qualifichi GCC 4.6 come un moderno compilatore, il risultato è che la direttiva in linea è ancora importante se scrivi attività ad alta intensità di CPU e sai dove si trova esattamente il collo di bottiglia.


6
Vorrei vedere altre prove a sostegno delle tue affermazioni. Fornisci il codice che stai testando e l'output dell'assemblatore con e senza parola chiave incorporata. Qualsiasi numero di cose avrebbe potuto darti benefici in termini di prestazioni.
void.pointer

1
Finalmente qualcuno che non solo ripete ciò che dicono gli altri, ma verifica effettivamente quelle affermazioni. Gcc in effetti considera ancora la parola chiave inline come un suggerimento (penso che clang la ignori completamente).
MikeMB,

@ void.pointer: perché è così difficile da credere? Se gli ottimizzatori fossero già perfetti, le nuove versioni non potrebbero migliorare le prestazioni del programma. Ma lo fanno regolarmente.
MikeMB,

3

In realtà, praticamente mai. Tutto quello che stai facendo è suggerire che il compilatore renda in linea una determinata funzione (ad esempio, sostituisci tutte le chiamate a questa funzione / con il suo corpo). Non ci sono garanzie, ovviamente: il compilatore può ignorare la direttiva.

Il compilatore farà generalmente un buon lavoro nel rilevare + ottimizzare cose come questa.


7
Il problema è che inlineha una differenza semantica in C ++ (ad es. Nel modo in cui vengono trattate definizioni multiple), che è importante in alcuni casi (ad es. Template).
Pavel Minaev,

4
inline viene utilizzato per risolvere i casi in cui un simbolo ha più definizioni. I modelli tuttavia sono già gestiti dalla lingua. Un'eccezione è una funzione modello specializzata che non ha più parametri modello (modello <>). Queste sono trattate più come funzioni che come modelli e quindi hanno bisogno della parola chiave incorporata per collegarsi.
deft_code

2

gcc di default non incorpora alcuna funzione durante la compilazione senza l'ottimizzazione abilitata. Non so di Visual Studio - deft_code

Ho verificato questo per Visual Studio 9 (15.00.30729.01) compilando con / FAcs e osservando il codice assembly: Il compilatore ha prodotto chiamate alle funzioni membro senza ottimizzazione abilitata in modalità debug . Anche se la funzione è contrassegnata con __forceinline , non viene prodotto alcun codice di runtime inline.


1
Abilita / Wall per sapere quali funzioni sono state contrassegnate come in linea ma non sono state effettivamente incorporate
paulm

0

Vuoi metterlo all'inizio, prima di restituire il tipo. Ma la maggior parte dei compilatori lo ignora. Se è definito e ha un blocco di codice più piccolo, la maggior parte dei compilatori lo considera comunque in linea.


0

A meno che tu non stia scrivendo una libreria o abbia motivi particolari, puoi invece dimenticarti inlinee usare invece l' ottimizzazione del tempo di collegamento . Rimuove il requisito secondo cui una definizione di funzione deve essere presente in un'intestazione affinché possa essere considerata come inline tra le unità di compilazione, che è esattamente ciò che inlineconsente.

(Ma vedi C'è qualche motivo per non usare l'ottimizzazione del tempo di collegamento? )


0

La parola chiave inline richiede al compilatore di sostituire la chiamata di funzione con il corpo della funzione, prima valuta l'espressione e quindi passa.Riduce il sovraccarico della chiamata di funzione in quanto non è necessario memorizzare l'indirizzo di ritorno e la memoria dello stack non è necessaria per la funzione argomenti.

Quando usare:

  • Per migliorare le prestazioni
  • Per ridurre l'overhead delle chiamate.
  • Dato che è solo una richiesta al compilatore, alcune funzioni non verranno incorporate * funzioni di grandi dimensioni
    • funzioni che hanno troppi argomenti condizionali
    • codice ricorsivo e codice con loop ecc.

Potrebbe essere utile sapere che in realtà non è così. Il livello di ottimizzazione da -O0 a - Ofast è ciò che determina se una funzione è incorporata o meno. Inline on compilation regolare (-O0) non incorporerà una funzione indipendentemente dal fatto che si usi inlineo meno in C e C ++. C Inline: stackoverflow.com/a/62287072/7194773 C ++ inline: stackoverflow.com/a/62230963/7194773
Lewis Kelsey

0

C ++ inline è totalmente diverso da C inline .

#include <iostream>
extern inline int i[];
int i [5];
struct c {
  int function (){return 1;} //implicitly inline
  static inline int j = 3; //explicitly inline
};
int main() {
  c j;
  std::cout << i;
}

inlineda solo influenza il compilatore, l'assemblatore e il linker. È una direttiva per il compilatore che dice di emettere un simbolo per questa funzione / dati solo se utilizzato nell'unità di traduzione, e se lo è, quindi come i metodi di classe, dire all'assemblatore di memorizzarli nella sezione .section .text.c::function(),"axG",@progbits,c::function(),comdato .section .bss.i,"awG",@nobits,i,comdatper i dati. Le istanze dei modelli vanno anche nei loro gruppi di comdat.

Questo segue .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Ad esempio, il nome della sezione è .text.c::function(). axGsignifica che la sezione è allocabile, eseguibile e in un gruppo, cioè verrà specificato un nome di gruppo (e non c'è un flag M quindi non verrà specificato alcun entsize); @progbitsindica che la sezione contiene dati e non è vuota; c::function()è il nome del gruppo e il gruppo hacomdatcollegamento che significa che in tutti i file oggetto, tutte le sezioni incontrate con questo nome di gruppo taggato con comdat verranno rimosse dall'eseguibile finale ad eccezione di 1 ovvero il compilatore si assicura che ci sia una sola definizione nell'unità di traduzione e quindi dice all'assemblatore di mettere nel suo gruppo nel file oggetto (1 sezione in 1 gruppo) e quindi il linker farà in modo che se qualsiasi file oggetto ha un gruppo con lo stesso nome, includerne solo uno nel file .exe finale. La differenza tra inlinee non utilizzo inlineè ora visibile all'assemblatore e di conseguenza al linker, perché non è memorizzato nel normale .datao .textecc dall'assemblatore a causa delle loro direttive.

static inlinein una classe significa che si tratta di una definizione di tipo e non di una dichiarazione (consente di definire un membro statico nella classe) e di renderlo in linea; ora si comporta come sopra.

static inlinenell'ambito del file riguarda solo il compilatore. Significa per il compilatore: emettere un simbolo per questa funzione / dati solo se viene utilizzato nell'unità di traduzione e farlo come un normale simbolo statico (memorizzare in.text /.data senza la direttiva .globl). Per l'assemblatore non esiste ora alcuna differenza tra staticestatic inline

extern inlineè una dichiarazione che significa che è necessario definire questo simbolo nell'unità di traduzione o generare un errore del compilatore; se è definito, trattalo come un normale inlinee per l'assemblatore e il linker non ci sarà alcuna differenza tra extern inlinee inline, quindi questa è solo una protezione del compilatore.

extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type

Tutto quanto sopra senza la riga di errore collassa a inline int i[5]. Ovviamente se avete fatto extern inline int i[] = {5};allora externsarebbe ignorato a causa della definizione esplicita attraverso l'assegnazione.

inlinesu uno spazio dei nomi, vedi questo e questo


-1

Quando si sviluppa e si inlineesegue il debug del codice, lasciarlo fuori. Complica il debug.

Il motivo principale per aggiungerli è aiutare a ottimizzare il codice generato. In genere questo inlineconsente di scambiare lo spazio di codice aumentato per la velocità, ma a volte consente di risparmiare spazio di codice e tempo di esecuzione.

Spendere questo tipo di pensiero sull'ottimizzazione delle prestazioni prima del completamento dell'algoritmo è l'ottimizzazione prematura .


12
inlinele funzioni in genere non sono integrate a meno che non vengano compilate con ottimizzazioni, quindi non influiscono in alcun modo sul debug. Ricorda che è un suggerimento, non una richiesta.
Pavel Minaev,

3
gcc di default non incorpora alcuna funzione durante la compilazione senza l'ottimizzazione abilitata. Non so di Visual Studio
deft_code il

Ho lavorato su un enorme progetto g ++ che aveva abilitato il debug. Forse altre opzioni lo hanno impedito, ma le inlinefunzioni sono state integrate. Era impossibile stabilire un breakpoint significativo in essi.
Wallyk,

2
abilitare il debug non smette di essere integrato in gcc. Se l'ottimizzazione è stata abilitata (-O1 o superiore), gcc proverà a includere i casi più ovvi. Tradizionalmente GDB ha avuto difficoltà con breakpoint e costruttori, specialmente costruttori in linea. Ma ciò è stato risolto nelle versioni recenti (almeno 6.7, forse prima).
deft_code

2
L'aggiunta inlinenon farà nulla per migliorare il codice su un compilatore moderno, che può capire se incorporare o meno da solo.
David Thornley,

-1

Quando uno dovrebbe essere in linea:

1.Quando si vuole evitare il sovraccarico di cose che accadono quando si chiama funzione come passaggio di parametri, trasferimento di controllo, ritorno di controllo ecc

2.La funzione dovrebbe essere piccola, chiamata frequentemente e rendere in linea è davvero vantaggioso poiché secondo la regola 80-20, cerca di rendere in linea quella funzione che ha un impatto notevole sulle prestazioni del programma.

Come sappiamo che inline è solo una richiesta per compilatore simile alla registrazione e ti costerà alla dimensione del codice oggetto.


"inline è solo una richiesta al compilatore simile alla registrazione" Sono simili perché non lo sono né le richieste né hanno a che fare con l'ottimizzazione. inlineha perso il suo status di suggerimento per l'ottimizzazione e la maggior parte dei compilatori lo utilizza solo per tenere conto di più definizioni, come dovrebbero essere le IMO. Inoltre, dal C ++ 11, registerè stato completamente deprecato per il suo significato precedente di "Conosco meglio il compilatore come ottimizzare": ora è solo una parola riservata senza alcun significato attuale.
underscore_d

@underscore_d: Gcc ascolta ancora fino inlinea un certo punto.
MikeMB,

-1

La funzione inline C ++ è un concetto potente che viene comunemente usato con le classi. Se una funzione è in linea, il compilatore inserisce una copia del codice di quella funzione in ciascun punto in cui la funzione viene chiamata al momento della compilazione.

Qualsiasi modifica a una funzione inline potrebbe richiedere la ricompilazione di tutti i client della funzione poiché il compilatore dovrebbe sostituire nuovamente tutto il codice, altrimenti continuerà con le funzionalità precedenti.

Per incorporare una funzione, posizionare la parola chiave in linea prima del nome della funzione e definire la funzione prima di effettuare qualsiasi chiamata alla funzione. Il compilatore può ignorare il qualificatore inline nel caso in cui la funzione definita sia più di una riga.

Una definizione di funzione in una definizione di classe è una definizione di funzione inline, anche senza l'uso dell'identificatore inline.

Di seguito è riportato un esempio, che utilizza la funzione incorporata per restituire un massimo di due numeri

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

per maggiori informazioni vedi qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.