2012-07-19 9 views
6

Supponiamo di definire BAR in foo.h. Ma foo.h potrebbe non esistere. Come posso includerlo, senza che il compilatore si lamentasse con me?Come si include un file di intestazione che può o non può esistere?

#include "foo.h" 

#ifndef BAR 
#define BAR 1 
#endif 

int main() 
{ 
    return BAR; 
} 

Pertanto, se BAR è stata definita come 2 in foo.h, allora il programma ritornerebbe 2 se foo.h esiste e 1 se foo.h non esiste.

+0

Fornire il proprio fallback foo.h che definisce 'BAR' e configurare il percorso di ricerca del compilatore di conseguenza? –

+0

Suppongo che potrei farlo. Perché il fallback foo.h dovrebbe includere qualcosa? – theanine

+0

possibile duplicato di [È possibile utilizzare il preprocessore C per stabilire se esiste un file?] (Http://stackoverflow.com/questions/142877/can-the-c-preprocess-be-used-to-tell-if- a-file-exists) –

risposta

8

In generale, è necessario eseguire un'operazione esterna per eseguire questa operazione, ad es. facendo qualcosa di simile a giocare con il percorso di ricerca (come suggerito nei commenti) e fornendo uno foo.h vuoto come fallback, o avvolgendo #include all'interno di uno #ifdef HAS_FOO_H ... #endif e impostando HAS_FOO_H da un commutatore (-DHAS_FOO_H per gcc/clang eccetera.).

Se si sa che si sta utilizzando un particolare compilatore e la portabilità non è un problema, si noti che alcuni compilatori supportano tra cui un file che può o non può esistere, come un'estensione. Ad esempio, vedere la funzionalità __has_include di clang.

+0

Il file di fallback 2nd foo.h è la soluzione più semplice. – theanine

+1

È anche una cattiva soluzione perché se il vero 'foo.h' cambia il suo header-guard interno' # define', si ottiene una rottura sottile. –

+1

Perché? Il fallback foo.h è vuoto. – theanine

6

Utilizzare uno strumento come GNU Autoconf, è per questo che è stato progettato. (Su Windows, potresti preferire usare CMake).

Quindi nel tuo configure.ac, avresti una linea come:

AC_CHECK_HEADERS([foo.h]) 

Il che, dopo l'esecuzione configure, definirebbero HAVE_FOO_H, che è possibile verificare in questo modo:

#ifdef HAVE_FOO_H 
#include "foo.h" 
#else 
#define BAR 1 
#endif 

Se intendo andare lungo il percorso degli autotools (che è autoconf e automake, perché funzionano bene insieme), suggerisco di iniziare con questo excellent tutorial.

+0

Gli autotools possono essere ... beh, dolorosi, ed è completamente inutile in questi giorni. Mac e Linux hanno un eccellente supporto CMake, e ci sono altri simpatici sistemi di compilazione (come [SCons] (http://www.scons.org/)). L'ESR ha un post particolarmente toccante che vale la pena considerare: [Autotools deve morire] (http://esr.ibiblio.org/?p=1877). – sfstewman

+4

Il dolore che CMake infligge supera di gran lunga gli autotools '. http://news.ycombinator.com/item?id=2357014. Costringe un modello di tipi di build ispirato a MSVC su unix land, viene fornito con un nuovo linguaggio di programmazione maldestro privo di strutture dati adeguate, esteso in modo ad-hoc con elementi casuali incorporati (qt4 !? fltk !?). Lo sproloquio dell'ESR è tutto vetriolo e nessuna sostanza. Ho usato CMake, SCons e autotools su diversi progetti e andrò ad autotools quasi ogni volta. Per sostituire gli autotools, non è necessario compilare makefile. Il modello di 'make' è sottilmente rotto e un sostituto deve capirlo. –

Problemi correlati