In a project I am interfacing between C++ and a C library that uses stdbool.h defined as such.
#ifndef _STDBOOL_H
#define _STDBOOL_H
/* C99 Boolean types for compilers without C99 support */
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */
#if !defined(__cplusplus)
#if !defined(__GNUC__)
/* _Bool builtin type is included in GCC */
typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
#endif
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif
#endif
Some structures have bool
members. So if I have one of these structures defined as local variables within a C++ function and pass it to a C function the sizes are inconsistent between C++ and C as bool is one bye in C++ and 4 in C.
Does anyone have any advice to how to overcome this without resorting to my current solution which is
//#define bool _Bool
#define bool unsigned char
Which is against the C99 standard for stdbool.h
I found the answer to my own question by finding a more compatible implementation of stdbool.h
that is compliant with the C99 standard.
#ifndef _STDBOOL_H
#define _STDBOOL_H
#include <stdint.h>
/* C99 Boolean types for compilers without C99 support */
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */
#if !defined(__cplusplus)
#if !defined(__GNUC__)
/* _Bool builtin type is included in GCC */
/* ISO C Standard: 5.2.5 An object declared as
type _Bool is large enough to store
the values 0 and 1. */
/* We choose 8 bit to match C++ */
/* It must also promote to integer */
typedef int8_t _Bool;
#endif
/* ISO C Standard: 7.16 Boolean type */
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif
#endif
This is taken from the Ada Class Library project.
Size is not the only thing that will be inconsistent here. In C++ bool is a keyword, and C++ guarantees that a bool can hold a value of either 1 or 0 and nothing else. C doesn't give you this guarantee.
That said, if interoperability between C and C++ is important you can emulate C's custom-made boolean by defining an identical one for C++ and using that instead of the builtin bool. That will be a tradeoff between a buggy boolean and identical behaviour between the C boolean and the C++ boolean.
Logically, you are not able to share source code between C and C++ with conflicting declarations for bool and have them link to each other.
The only way you can share code and link is via an intermediary datastructure. Unfortunately, from what I understand, you can't modify the code that defines the interface between your C++ program and C library. If you could, I'd suggest using something like:
union boolean {
bool value_cpp;
int value_c;
};
// padding may be necessary depending on endianness
The effect of which will be to make the datatype the same width in both languages; conversion to the native data type will need to be performed at both ends. Swap the use of bool for boolean in the library function definition, fiddle code in the library to convert, and you're done.
So, what you're going to have to do instead is create a shim between the C++ program and the C library.
You have:
extern "C" bool library_func_1(int i, char c, bool b);
And you need to create:
bool library_func_1_cpp(int i, char c, bool b)
{
int result = library_func_1(i, c, static_cast<int>(b));
return (result==true);
}
And now call library_func_1_cpp instead.