Domanda

Quali sono i vantaggi di un'intestazione solo biblioteca e perché lo scrivi in questo modo si oppone a mettere l'implementazione in file separato?

È stato utile?

Soluzione

Ci sono situazioni quando una biblioteca di sola intestazione è l'unica opzione, ad esempio quando si tratta di modelli.

Avere una biblioteca di sola intestazione significa anche che non devi preoccuparti di piattaforme diverse in cui potrebbe essere utilizzata la biblioteca.Quando si seppierà l'implementazione, di solito lo fai per nascondere i dettagli di implementazione e distribuire la libreria come una combinazione di intestazioni e librerie (lib, dll o .so Files).Questi ovviamente devono essere compilati per tutti i diversi sistemi operativi / versioni che offri il supporto.

Potresti anche distribuire i file di implementazione, ma ciò significherebbe un passaggio aggiuntivo per la compilazione dell'utente, la compilazione della libreria prima di utilizzarlo.

Certo, questo si applica a caso per caso .Ad esempio, le librerie di sola intestazione a volte aumentano le dimensioni del codice del codice & tempi di compilazione.

Altri suggerimenti

Vantaggi della libreria di sola intestazione:

    .
  • Semplifica il processo di costruzione. Non è necessario creare la libreria e non è necessario specificare la libreria compilata durante la fase di collegamento della build. Se si dispone di una libreria compilata, probabilmente vorrai costruire più versioni di esso: una compilata con il debug abilitato, un altro con ottimizzazione abilitata e possibilmente ancora un altro spogliato di simboli. E forse ancora di più per un sistema multi-piattaforma.

    Svantaggi di una libreria di sola intestazione:

      .
    • file di oggetti più grandi. Ogni metodo in linea dalla biblioteca che viene utilizzato in un file sorgente riceverà anche un simbolo debole, definizione fuori linea nel file oggetto compilato per quel file sorgente. Questo rallenta il compilatore e rallenta anche il linker. Il compilatore deve generare tutto quel gonfiore e quindi il linker deve filtrarlo.

    • Compilazione più lunga. Oltre al problema della boat menzionato sopra, la compilazione richiederà più tempo perché le intestazioni sono intrinsecamente più grandi con una libreria di sola intestazione rispetto a una biblioteca compilata. Quelle grandi intestazioni devono essere analizzate per ogni file sorgente che utilizza la biblioteca. Un altro fattore è che tali file di intestazione in una libreria solo per intestazione devono generare intestazioni #include necessarie dalle definizioni in linea, nonché le intestazioni che sarebbero necessarie la libreria è stata costruita come una libreria compilata.

    • Più compilazione aggrovigliata. Ottieni molte più dipendenze con una libreria di sola intestazione a causa di quei generatori di generatori extra necessari con una libreria di sola intestazione. Modificare l'implementazione di una funzione chiave nella libreria e potresti aver bisogno di ricompilare l'intero progetto. Effettuare quella modifica nel file sorgente per una libreria compilata e tutto ciò che devi fare è ricompilare che un file di origine della libreria, aggiornare la libreria compilata con quel nuovo file .o, e ricollegare l'applicazione.

    • più difficile per l'umano da leggere. Anche con la migliore documentazione, gli utenti di una biblioteca spesso devono ricorrere a leggere le intestazioni per la biblioteca. Le intestazioni in una biblioteca di sola intestazione sono piene di dettagli di implementazione che ostacolano l'interfaccia. Con una biblioteca compilata, tutto ciò che vedi è l'interfaccia e un breve commento su ciò che lo fa l'implementazione, e questo di solito è tutto ciò che desideri. Questo è davvero tutto ciò che dovresti volere. Non dovresti sapere i dettagli di implementazione per sapere come utilizzare la libreria.

So che questo è un vecchio filo, ma nessuno ha menzionato interfacce ABI o problemi specifici del compilatore. Quindi ho pensato che vorrei.

Questo è fondamentalmente basato sul concetto di voi che scrivete una libreria con un'intestazione per distribuire alle persone o riutilizzare te stesso vs avere tutto in un'intestazione. Se stai pensando di riutilizzare un'intestazione e un file di origine e ricompilazione di questi in ogni progetto, allora questo non si applica davvero.

Fondamentalmente se si compila il codice C ++ e crei una libreria con un compilatore, quindi l'utente tenta di utilizzare quella libreria con un diverso compilatore o una versione diversa dello stesso compilatore, è possibile ottenere errori del linker o uno strano comportamento di runtime dovuto al binario Incompatibilità.

Ad esempio i fornitori di compilatore cambiano spesso la loro implementazione della STL tra le versioni. Se hai una funzione in una libreria che accetta un STD :: Vector, allora si aspetta che i byte in quella classe siano organizzati nel modo in cui sono stati disposti quando la biblioteca è stata compilata. Se, in una nuova versione del compilatore, il fornitore ha fatto miglioramenti di efficienza a STD :: Vector, quindi il codice dell'utente vede la nuova classe che può avere una struttura diversa e passa quella nuova struttura nella tua libreria. Tutto va in discesa da lì ... Ecco perché è consigliato non superare gli oggetti STL attraverso i confini della biblioteca. Lo stesso vale per i tipi di tempo run-time (CRT).

Mentre parli del CRT, la tua biblioteca e il codice sorgente dell'utente in genere devono essere collegati allo stesso CRT. Con Visual Studio se si crea la tua libreria utilizzando il CRT multithread, ma gli utenti sono collegati contro il CRT di debug multithreading, quindi avrai problemi di collegamento perché la tua libreria potrebbe non trovare i simboli di cui ha bisogno. Non riesco a ricordare quale funzione è stata, ma per Visual Studio 2015 Microsoft ha fatto una funzione CRT in linea. All'improvviso era nell'intestazione non la Biblioteca CRT in modo che le biblioteche che si aspettavano di trovarlo al momento del collegamento non potessero più fare e questo generato errori di collegamento. Il risultato è stato che queste biblioteche avevano bisogno di ricompilazione con Visual Studio 2015.

È inoltre possibile ottenere errori di collegamento o strano comportamento se si utilizza l'API di Windows ma si crea con diverse impostazioni Unicode all'utente della libreria. Questo perché l'API di Windows ha funzioni che utilizzano stringhe Unicode o ASCII e macro / definisce che utilizzano automaticamente i tipi corretti in base alle impostazioni Unicode del progetto. Se si passa una stringa attraverso il limite della biblioteca che è il tipo sbagliato, le cose si rompono in fase di esecuzione. Oppure potresti scoprire che il programma non si collega in primo luogo.

Queste cose sono anche vere per il passaggio di oggetti / tipi attraverso i confini della biblioteca da altre biblioteche di terze parti (E.G un vettore di Eigen o una matrice GSL). Se la libreria di terze parti cambia la sua intestazione tra la compilazione della libreria e il tuo utente che compila il loro codice, le cose si rompono.

Fondamentalmente per essere sicuri le uniche cose che puoi passare attraverso i confini della biblioteca sono costruiti in tipi e semplici vecchi dati (POD). Idealmente qualsiasi baccello dovrebbe essere in strutture che sono definite nelle proprie intestazioni e non fanno affidamento su intestazioni di terze parti.

Se si fornisce un'intestazione solo libreria, quindi tutto il codice viene compilato con le stesse impostazioni del compilatore e contro gli stessi intestazioni, quindi molti di questi problemi vanno via (fornendo la versione di terzi librerie parzialmente te e il tuo utente utilizzati è compatibile con API ).

Tuttavia ci sono negativi che sono stati menzionati sopra, come l'aumento del tempo di compilazione. Inoltre potresti gestire un business in modo da non voler consegnare tutti i tuoi dettagli di implementazione del codice sorgente a tutti i tuoi utenti nel caso uno di loro lo ruba.

Il principale "beneficio" è che richiede di consegnare il codice sorgente, quindi finirai con rapporti di errore su macchine e con compilatori che hai mai sentito di.Quando la biblioteca è interamente modelli, non hai molta scelta, ma quando hai la scelta, l'intestazione è solitamente un povero Scelta ingegneristica.(D'altra parte, naturalmente, l'intestazione significa solo questo Non è necessario documentare alcuna procedura di integrazione.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top