Closed mlubin closed 6 years ago
I like the char
option. It seems the easiest solution. What do you think @goulart-paul ?
The only purpose of the above is to ensure that the QDLDL_bool
we define will make sense to the C compiler, which will not be the case if we have a C89 only compiler and we ask for _Bool
.
It might be better to check for compiler support of '_Bool' in cmake directly before building qdldl, using something like https://cmake.org/cmake/help/v3.0/module/CheckCSourceCompiles.html
The process in cmake could be:
Include a small check in cmake to see if test code with a _Bool
compiles.
Define QDLDL_BOOL_TYPE accordingly within cmake, taking it as either int
or _Bool
depending on the outcome of step 1.
Put typedef @QDLDL_BOOL_TYPE@ QDLDL_bool;
into qdldl_types.h.in
as a single line instead of switching on __STDC_VERSION__
as above.
In this way the header would be unambiguous about the logical type we use and we would be sure that the header is consistent with what we actually built.
If the above seems like it would fix the problem with C++ compatibility I can try it.
From what I can tell, _Bool
will not work for C++. It's not defined in the C++ standard or supported by the C++ compilers that I tried. I also tried using bool
and including stdbool.h
but that didn't work either on the C++ side.
Another option would be to just make it an enum
, e.g.
typedef enum _QDLDL_bool { false, true } QDLDL_bool;
That ends up as the same size as int
I think, which is not quite as compact as it could be but better than nothing. The only point of any of this was to avoid it being long long
when we define QDLDL_int
that way.
enum
s are also a bit problematic to use at library boundaries because their size is not defined in the standard. If you compile qdldl into a shared library with compiler 1 and try to link to it with compiler 2, you have a similar issue.
Do you have an objection to char
?
Not really, no. It was unclear to me when writing this whether forcing the type to be 8 bits exactly might be slower than allowing it to be whatever is the most efficient size for the platform (i.e. I would have preferred int_fast8_t
, but that is also C99 only). I can't say for sure if that's anything beyond a hypothetical concern though.
That's also hard to test since I don't know on which platforms int_fast8_t
is strictly larger than char
.
If char
is too awkward as a bool store, int
is also reasonable. You can also ask for an int*
for the bool storage in the header and cast it to something else. You have to be careful about memory alignment issues if you're casting it to a pointer to a type of a different size than int
, however.
I have proposed a fix in #12 that changes the definition of the bool type to unsigned char
.
fixed in #12
I know I'm responsible for suggesting this, but I realized there's a design issue with
in
qdldl_types.h
. If you includeqdldl.h
from C++, the second case will be hit regardless of how qdldl was compiled. I think the logic behind this compiler check is flawed, because it's impossible to know at header include time which C compiler was used for qdlql. I did a bit of searching and it seems like there's no good solution for an interoperable boolean type between C and C++. FortunatelyQDLDL_bool
does very little in the header, it's just used for allocating a work vector. It would be safe to move this C99 check into the source file and use another type in the header. I also triedand this seems to work fine and accomplish the goal of a 1-byte type that can store 0/1 values.