How to avoid the C-header overwriting C ++ native type

First I have to explain my ...

Situation

  • I have this microcontroller code (plain old C ) that includes bool.h with the following contents with stdbool.h apparently not available, especially with Visual Studio 2008, which is my current IDE for VC ++ and C # (see . below):

    #ifndef CUSTOM_BOOL #define CUSTOM_BOOL #ifdef __cplusplus extern "C" { #endif // #ifdef __cplusplus #ifndef bool #define bool unsigned char #endif #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif #ifdef __cplusplus } #endif // #ifdef __cplusplus #endif // #ifndef CUSTOM_BOOL 
  • Now I need the functionality of this microcontroller code in a C # project. Therefore, I created an intermediate Visual C ++ project containing managed classes that wrap this microcontroller code.

  • Since this wrapper project (VC ++) twists the C code, it also has #include "bool.h" (indirectly, but this means that another header is included, which includes bool.h itself), but I I think that irrelevant details). Now here is my ...

Problem

Due to the fact that bool.h is included in the VC ++ project, this project should provide functions that return a "real" bool ("real" here means a type that is recognized as bool by C # when using a VC ++ project ), unfortunately, bool in VC ++ code also falls into the preprocessor and is replaced by unsigned char . What happens is that C # eventually complains that converting from unsigned char to bool is not allowed. Everything is in order, and I understand why this is happening. So here is my ...

Question

How can I solve this problem in a "clean" way. My current solution is that after turning on bool.h and right before the start of the VC ++ code, I will again reject bool and friends as follows:

 #ifdef bool #undef bool #endif #ifdef true #undef true #endif #ifdef false #undef false #endif 

It works, but it breaks my heart β€” the way of programming. Is there a proper way to fix this? Or the problem may be earlier? Should I instead define bool instead of bool ? According to my search on interwebz, there is no general β€œstandard” way to define bool (or BOOL?) In project C (C99 is not supported), which everyone will agree on.

+4
source share
3 answers

So it looks like the microcontroller project has just created a new data type and named it bool, which now conflicts with the fact that bool is a keyword (along with true and false)? My suggestions (in order of preference):

Solution 1: Fix the microcontroller project. Do a global search and replace with bool and replace it with something less controversial. Perhaps C_Boolean, C_True and C_False. It is unlikely to cause any future conflicts and is fairly simple to do using regular expressions.

Solution 2: Convert the microcontroller project to C ++. This allows direct use of bool, true and false (as keywords), and you can simply exclude macros. This can be difficult if the microcontroller code uses syntax that is not compatible with C ++.

Solution 3. Do what you have already done. Create a shell that will clear after you enable your microcontroller code. I have code that relies on overriding the extern keyword, and this becomes the only safe way for me. It's fragile, though ... you'll probably have to fix it in the future when something unrelated destroys the include structure.

Also, I'm not sure if the original author thinks that extern "C" wrappers do, but they do not affect the macros defined. You may have cut out some of the things this would have affected, but the macros are not affected by the link builder conventions.

+1
source

You can convert the return value (char) to a boolean value using the operator. In this case, for example, you can simply compare the return value as follows:

bool b = 0! = functionthaturnurnsaboolean ();

Note that I am not using 1, since the usual definition of a boolean is 0 for false, something else otherwise.

Another solution would be to simply use a different type of return value. An integer should work well.

Edit: In the light of the comment - you can also just create an interface that calls these functions and returns the boolean value of C #.

 bool interfacefunction() { return function() != 0; } 
0
source

Thanks to Keith Thompson (comment on this) and Speed8ump's answer, I got another idea:

bool.h:

 #ifndef CUSTOM_BOOL #define CUSTOM_BOOL #ifndef __cplusplus #ifndef bool #define bool unsigned char #endif #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif #endif // #ifndef __cplusplus #endif // #ifndef CUSTOM_BOOL 

It works like a charm, and I think this is a cleaner solution than before. But nonetheless, feel free to comment or provide more / better answers.

0
source

Source: https://habr.com/ru/post/1498023/


All Articles