La configurazione relativa definisce nell'intestazione pubblica?

2

Supponiamo che tu stia costruendo delle librerie, C o C ++ non ha importanza per questa domanda, IMO. Le funzionalità (o la loro implementazione) dipendono dalle funzionalità del sistema di destinazione.

Un esempio semplice, probabilmente forzato: alcune funzionalità dipendono dal fatto che il sistema abbia o meno un% di lavoroint64_t (tipo intero a 64 bit) o meno.

Supponendo uno stile GNU ./configure , si finirebbe con un config.h con contenuti come:

// ...
#define HAVE_INT64_T 1
// ...

Si potrebbe quindi includere questo config.h (probabilmente con un nome migliore) nell'intestazione della libreria pubblica library.h , e lasciare che le caratteristiche dipendano da HAVE_INT64_T :

// ...
#include "config.h"
// ...
#ifdef HAVE_INT64_T
#define AWESOME_FEATURE(x) ((int64_t)(x) + 1)
extern int64_t const stupid_value;
#endif
// ...

Ora, se stai creando un'applicazione su questa libreria e i tuoi requisiti su #define HAVE_INT64_T 1 sono diversi, ad es. più severo di quelli della libreria , quando si fa nei guai:

// ...
#include "app-config.h" // does NOT define HAVE_INT64_T
#include <library.h> // defines HAVE_INT64_T
// -> stuff breaks

Quindi: È considerata una cattiva pratica mettere "configurazione" #define s nelle intestazioni delle librerie pubbliche? E se sì, quali sono le alternative?

    
posta Daniel Jour 18.05.2016 - 22:46
fonte

1 risposta

2

Non è certamente una cattiva pratica mantenere gli elementi di configurazione della libreria raggruppati in un'intestazione di configurazione comune. Anzi ! Facilita la portabilità ad altri ambienti / architetture e facilita la manutenzione / distribuzione. E la configurazione dell'applicazione potrebbe essere diversa dalla configurazione della libreria.

L'unico problema è evitare la collisione tra l'applicazione e i componenti della libreria. In effetti, questo problema è simile alla denominazione di include guards : non devi utilizzare identificatori che potrebbero essere utilizzato inavvertitamente per altri scopi in altri contesti. Il nome dovrebbe essere abbastanza lungo e rendere esplicito lo scopo dell'identificatore (ad esempio, utilizzare una convenzione di denominazione con la libreria che definisce a partire dal nome della libreria).

In alcuni casi (di gran lunga non tutti, purtroppo) è possibile utilizzare le funzionalità del linguaggio (ad es. definizioni costanti, definizioni dei tipi, modelli come std::enable_if ) e beneficiano dell'ottimizzatore (ad es. eliminazione del codice di eliminazione da parte dell'ottimizzatore) per ottenere gli stessi risultati anziché utilizzando le direttive del preprocessore. In questo caso è possibile evitare facilmente la collisione utilizzando gli spazi dei nomi C ++. Ma questo non è sempre fattibile.

    
risposta data 18.05.2016 - 23:56
fonte

Leggi altre domande sui tag