2015-09-17 15 views
5

Breve descrizione:Esclusione di intestazione?

Header.h ha #include <stdbool.h> che ha una macro per _Bool in c.

file.cpp include Header.h, ma poiché file.cpp è C++, ha il bool come tipo nativo. Ora Lint si lamenta di un insieme di cose a causa di questo (ridichiarazione, metodi non esistenti ecc.). C'è un modo per impedire l'inclusione di <stdbool.h> in file.cpp senza toccare Header.h?

Se la mia descrizione di un problema sembra ridicola, per favore butta pomodori a me :) Altrimenti, grazie per l'aiuto.

Edit: Ora pensando a questo nuovo: conoscere i concetti di base della compilazione e il collegamento Avrei dovuto capire che 'escluso' un po 'di intestazione nel file di downstream/intestazione suona divertente e non dovrebbe essere possibile senza cludges. Ma ancora, grazie per l'aiuto. Un altro piccolo mattone per la mia comprensione di questo.

+7

Protesta con il rivenditore della tua biblioteca. 'stdbool.h' non dovrebbe definire' bool' e gli amici come macro in C++. Nel frattempo, '# undef'. –

+2

Puoi modificare 'header.h'? Quindi basta aggiungere i controlli condizionali del preprocessore per '__cplusplus' prima di includere' '. E potresti voler dare un'occhiata a quel tuo linter, non sembra gestire molto bene il C++, o non fa molto bene la pre-elaborazione. –

+2

@ T.C. non è così semplice, il C++ 98 non dice nulla su '' quindi i suoi effetti in C++ 98 non sono specificati. GCC '' definisce le macro per C++ 98, perché le ragioni. Ragioni schifosi. Almeno fa '#define bool bool' in C++, non' #define bool _Bool' che è attivamente dannoso. –

risposta

9

È possibile creare il proprio stdbool.h e inserirlo in precedenza nel percorso di inclusione in modo che venga trovato prima del sistema. Questo è un comportamento tecnicamente indefinito, ma hai un problema con lo <stdbool.h>, quindi è un modo per ovviare a questo problema. La propria versione potrebbe essere sia vuota (se verrà incluso solo dai file C++), o se non è possibile impedire che anche utilizzato da file C allora si potrebbe fare:

#if __cplusplus 
# define __bool_true_false_are_defined 1 
#elif defined(__GNUC__) 
// include the real stdbool.h using the GNU #include_next extension 
# include_next <stdbool.h> 
#else 
// define the C macros ourselves 
# define __bool_true_false_are_defined 1 
# define bool _Bool 
# define true 1 
# define false 0 
#endif 

una soluzione più pulita sarebbe quella di farlo in file.cppprima tra cui Header.h:

#include <stdbool.h> 
// Undo the effects of the broken <stdbool.h> that is not C++ compatible 
#undef true 
#undef false 
#undef bool 
#include "Header.h" 

Ora, quando Header.h include <stdbool.h> essa non avrà alcun effetto perché è già stato incluso. Questo modo è tecnicamente non valido (vedi commento sotto), ma in pratica funzionerà quasi certamente in modo portabile.

Deve essere fatto in ogni file che include Header.h, quindi è possibile racchiuderlo in una nuova intestazione e utilizzarlo al posto di Header.h ad es. CleanHeader.h che contiene:

#ifndef CLEAN_HEADER_H 
#define CLEAN_HEADER_H 
// use this instead of Header.h to work around a broken <stdbool.h> 
# include <stdbool.h> 
# ifdef __cplusplus 
// Undo the effects of the broken <stdbool.h> that is not C++ compatible 
# undef true 
# undef false 
# undef bool 
#e ndif 
# include "Header.h" 
#endif 
+1

Il secondo approccio viola tecnicamente [macro.names]/p2 :) –

+1

@ T.C. doh! Hai perfettamente ragione, correggerò la mia richiesta è valida.Penso che sia la soluzione migliore, dal momento che provare a scrivere un C++ valido con uno std :: lib non conforme è difficile! –