Posted on Sun Apr 2, 2017
I’ve registered my CCExceptions project with Travis CI; it is the first project I integrated with Travis. It worked but I had to fight with the build script… the platform uses Ubuntu, and I know nothing of this distribution’s packages. For some reasons their default gnu+Linux build infrastructure does not come with the latest gnu Autoconf and gcc; the build script has to install them. The latest Autoconf (2.69) was released in 2012, we are now in 2017…
I want to attempt a build under Mac OS X: it will be more painful because I literally never used this platform.
I’ve also tried to integrate the project with Coverity. This failed very early. The reason is that the project makes use of gcc extensions that, as far as I can tell, are not recognised by Coverity’s tools. This was to be expected! It hurts me.
In this project: I want to use the features of the C11 standard; I want to mimic
single–inheritance with nested structs; I do not want to use void*
pointers to structs and cast them to the appropriate data type.
The latest requirement is the one that bites: to avoid cluttering the code with cast operators and still obtain static–types validation, we have to do something clever. Given the struct hierarchy:
typedef struct alpha_t alpha_t; typedef struct beta_t beta_t; struct alpha_t { int A; }; struct beta_t { alpha_t parent; int B; };
there need to be two mechanisms:
alpha_t
from a pointer to beta_t
.
beta_t
from a pointer to alpha_t
.
Using gcc’s -fplan9-extensions is an easy and friendly solution; but it is not standard. So what do I do?
I’ve opened a new (at present private) branch in the project to attempt a port to the standard language and see what happens. This has led to reconsiderations, type name changes and so on.
The basic idea I’m experimenting with is to define preprocessor macros which expand
to _Generic
uses:
#define cast_to_alpha(S) _Generic((S), ...) #define cast_to_beta(S) _Generic((S), ...)
so that:
cast_to_alpha()
is applied to a pointer to alpha_t
or
beta_t
or another struct that contains an alpha_t
field: it
evaluates to the appropriate pointer to alpha_t
.
cast_to_beta()
is applied to a pointer to alpha_t
or
beta_t
or another struct that contains a beta_t
field: it
evaluates to the appropriate pointer to beta_t
.
this is done with cast functions, C language: cast functions.
About this solution: it is a bit verbose; it is not totally safe; it requires some hand–written code, whose generation can be automated; it is unfriendly to extend a hierarchy defined in a library with data types defined in another library.
Life is hard.