ProgrammazioneIngegnere C/C++

Parla delle differenze tra funzioni dichiarate come inline e funzioni normali in C. Quali sono le limitazioni, come dichiarare correttamente le funzioni inline quando si lavora con più file sorgente, quali errori commettono spesso gli sviluppatori?

Supera i colloqui con l'assistente IA Hintsage

Risposta

inline è un suggerimento per il compilatore di sostituire la chiamata della funzione con il suo corpo (inserimento del codice). Ciò può velocizzare l'esecuzione (nessun overhead per la chiamata), ma porta a un aumento delle dimensioni del binario.

Sintassi:

inline int square(int x) { return x * x; }

Il compilatore può ignorare inline. Per avere visibilità e implementazione simultanea della funzione in file diversi si utilizza:

// header.h inline int min(int a, int b) { return a < b ? a : b; }

Il corpo della funzione deve essere accessibile in ogni file dove viene chiamata la funzione inline, quindi il modo normale è definire la funzione nel file header.

Se si dichiara e definisce una funzione inline solo in un file .c, altri moduli non potranno utilizzarla e si verificheranno errori di linking (riferimento non definito).

Domanda insidiosa

Qual è la differenza tra queste dichiarazioni nel file di intestazione?

inline int foo(int x) { return x + 1; } static inline int bar(int x) { return x + 1; }

Risposta:

  • inline int foo(...) porta al fatto che la funzione può avere molteplici definizioni deboli (one definition rule). Se dallo stesso header sono inclusi più file .c, il linker può restituire un errore di definizione multipla.
  • static inline rende la funzione interna per ogni modulo: ogni punto di collegamento riceve la propria copia, quindi non ci saranno problemi durante il linking. Questo è il modo più sicuro per le funzioni inline negli header.

Esempi di errori reali a causa della mancanza di conoscenza delle complessità del tema


Storia

Nel file della libreria delle funzioni matematiche erano definite molte funzioni helper inline. Quando si cercava di utilizzarle da altri moduli si verificavano errori di linking, perché le definizioni erano visibili solo in un file oggetto.


Storia

Dopo aver spostato le funzioni inline dal file .c all'header, il progetto ha iniziato a cadere durante il linking: il linker si lamentava di definizioni multiple della stessa funzione. È stato corretto sostituendole con static inline nei file header.


Storia

Nell'ottimizzazione di un algoritmo interno sono state utilizzate le inline per le funzioni "critiche", aspettandosi un'accelerazione. Ma il compilatore ha ignorato il suggerimento e il profiler ha mostrato che i costi delle chiamate non sono diminuiti. Il problema è stato risolto solo dopo un'analisi manuale delle opzioni di ottimizzazione del compilatore.