Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header exclusion?

Short description:

Header.h has #include <stdbool.h> which has a Macro for _Bool in c.

file.cpp includes Header.h, but since file.cpp is C++ - it has bool as a native type. Now lint complains about a set of things due this (redeclaration, non-existing methods etc.). Is there a way to prevent inclusion of <stdbool.h> in file.cpp without touching Header.h?

If my description of a problem looks ridiculous - please throw tomatoes at me :) Otherwise, thanks for help.

Edit: Now thinking of this again: knowing the basic concepts of compilation and linking I should have realized that 'excluding' some header in downstream file/header sounds funny and should not be possible without cludges. But still, thanks for help. Another small brick to my understanding of this.

like image 484
Zloj Avatar asked Sep 17 '15 10:09

Zloj


1 Answers

You could create your own stdbool.h and put it earlier in the include path so it is found before the system one. That's technically undefined behaviour, but you have a broken <stdbool.h> so it's one way to work around that. Your own version could either be empty (if it will only be included by C++ files) or if you can't prevent it also being used by C files then you could do:

#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

A cleaner solution would be to do this in file.cpp before including 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"

Now when Header.h includes <stdbool.h> it will have no effect because it's already been included. This way is technically invalid (see comment below), but in practice will almost certainly work portably.

It needs to be done in every file that includes Header.h, so you could wrap it up in a new header and use that instead of Header.h e.g. CleanHeader.h that contains:

#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
like image 116
Jonathan Wakely Avatar answered Nov 27 '22 04:11

Jonathan Wakely