Quando una funzione deve essere dichiarata in linea in C ++

2

Sto provando a riscrivere un codice che ho scritto tempo fa usando alcune buone pratiche C ++. Per raggiungere tale obiettivo sto usando come riferimento Efficace C ++ (1) e convenzione di codifica google (2). Secondo (2) una funzione dovrebbe essere dichiarata in linea se è 10 righe o meno, secondo (1) inoltre il compilatore potrebbe ignorare la direttiva inline, ad esempio quando ci sono loop o ricorsione (solo un esempio è fornito in modo da conosco tutti i casi che verrebbero ignorati dal compilatore).

Diciamo che ho 2 funzioni, la prima è 10 righe, e non c'è chiamata a nessuna altra funzione e nessun riferimento esterno in generale. Il secondo presuppone che siano ancora 10 righe ma ad un certo punto c'è una chiamata al primo

Qualcosa come

Type1 f(Type2 arg) {
   //10 lines of self contained code
}

Type3 g(Type4 arg) {
   //0 <= n <= 8 lines of code
   //g(x);
   //9 - n lines of code
}

Vorrei dichiarare il f in linea, a causa del suggerimento di google (pienamente giustificato) Ma sarei perplesso circa g quale sarebbe una buona pratica qui? Dichiarerebbe g come inline ignorato dal compilatore? In caso contrario, posso ancora usufruire dei vantaggi della direttiva inline?

    
posta user8469759 05.01.2017 - 13:57
fonte

1 risposta

9

In C ++, lo specificatore inline non influisce sul fatto che un compilatore inline una chiamata di funzione. Ha effetti che rendono possibile l'inlining, ma questo non è lo scopo principale. Se hai una funzione di helper privata che vuoi essere inline, assicurati invece che abbia un collegamento interno - ad es. inserendolo in uno spazio dei nomi anonimo (C ++ 11). È possibile accedere a una dichiarazione con collegamento interno solo dall'unità di compilazione corrente.

Una funzione inline può avere più definizioni. Questo è importante quando si definisce una funzione all'interno di un file di intestazione. Di solito, si dichiarano le funzioni in un'intestazione e si implementa in un file .cpp. Altre unità di compilazione includono la dichiarazione nell'intestazione e sono successivamente collegate alla definizione. Ma se la funzione è definita in un'intestazione, la stessa funzione ora esiste in più unità di compilazione. Quando sono collegati, il linker vede queste definizioni multiple per la tua funzione. Qual è la definizione corretta? Il linker genererà un errore.

Con un identificatore inline , dici al linker che queste definizioni multiple sono OK e si riferiscono tutte alla stessa funzione. Inoltre, la definizione di una funzione inline deve essere presente nella stessa unità di compilazione.

Alcune funzioni sono implicitamente in linea, in particolare qualsiasi metodo e funzione all'interno di una dichiarazione di classe:

class Foo {
public:
  void method() { /* implicitly inline */ }
  static void static_method() { /* implicitly inline */ }
  friend void friend_function() { /* implicitly inline */ }
};

void free_function() { /* not implicitly inline */ }

Non dichiarare una funzione come inline perché è breve. Dichiaralo come in linea perché lo hai definito in un'intestazione.

Ulteriori letture: inline specificatore su cppreference.com

Lo stile di guida di Google che citi non discute quando deve essere utilizzata la parola chiave inline , ma se le funzioni devono essere implementate in linea (ad esempio nel file di intestazione). Per funzioni semplici come i getter in una classe questo di solito è perfettamente soddisfacente. Per le funzioni più grandi e più complicate, di solito è meglio implementarle separatamente (sebbene ciò non sia possibile per i modelli).

    
risposta data 05.01.2017 - 14:41
fonte

Leggi altre domande sui tag